Designing Security Into Your Application
Every day we are bombarded with articles relating to the latest security breach and how cyber-crime is an ever-increasing market for the unscrupulous among us. While it is always hard to apportion blame in these instances; security is very much like an onion, being many layered. The more layers that you have, the less likely you are to cry.
Let’s take a look at three external security layers that we can wrap around our application or service.
- Service/Application account: The security context in which the code executes;
- Linux Capabilities: Granular assignment of administrative privileges;
- Mandatory Access Control Lists: Quantify with exact precision what the application can have access to.
Because of the free nature of Linux, many internet facing or consumer items are based on this OS. If you are developing an internet connected refrigerator to reorder your favorite beer before the big game on Saturday, you don’t want to have to worry about licenses for the operating system that runs within the fridge. This means that you, as a developer, will increasingly work with applications that sit on top of Linux.
1. The first thing to consider is creating a user account for your application. Your application can then run in the context of this user, with only the privileges that it needs. This user should not be able to run an interactive login shell, ensuring that your account does not become a gateway into the system. We don’t want rye-bread appearing in the fridge in-place of the hallowed beer. A user that cannot log in to the system interactively is shown in the following extract from the /etc/passwdfile on a Raspberry Pi running Debian Linux:
The user account name is system-timesysnc, the first value. The shell is shown as the last value of /bin/false. This prevents the user from running an interactive shell, locally or remotely. The user account you create for your application is now effectively restricted to the code that you permit within the application
2. Your application or service may need super-user access. If it does need such access, then please don’t make use of the Set User ID bit for this. The Set User ID or SUID bit is a Linux permission usually used for giving the application root access to the system. The application is executed by the service account you created but gains full access as root. This works perfectly well, in much the same way as removing locks to your house gives great access to your home. Given this scenario, you should realize that giving your application too many rights is not a great idea. The Internet-enabled fridge now is able to order our beer, which is good, and also empty our bank account, not so good.
Taking the example that your application may need to read a single restricted file, but nothing else is required with elevated privileges, Capabilities is a better approach. Choosing to use Linux Capabilities in place of the SUID bit, we can be very granular with the root privileges that we assign.
Assigning the CAP_DAC_READ_SEARCH capability to your application, instead of the SUID bit, we are able to read restricted files but not write to those files. No other supervisory permissions are applied. With Capabilities, we are able to be very granular in the assignment of privileges, this is not possible with the SUID bit which gives all or nothing. Of course, security is still controlled by what we program into the application or service but we double up with the extra security granted through Capabilities. For more information on what Capabilities are available, on any Linux system, use the command:
man 7 capabilities
3. Utilize Mandatory Access Control Lists. Mandatory Access Control Lists (MACL) systems like SELinux or AppArmor takes your application security to the next level of granularity. For example, a MACL can ensure that your application can only read from the /etc/shadowfile even if it is executed with the Linux Capability we saw previously. Mandatory Access Control Lists affect the root account as well as standard users, essentially in preventing malicious attacks within trusted applications. AppArmor profiles can be added to /etc/apparmor.d/ during the installation of the application or service. An example of restricting read access to the shadow file is shown in the following policy extract.
It has been proven that adequate use of Mandatory Access Control Lists does prevent malicious activity on your system. Designing your application to make use of AppArmor or SELinux is going to improve the security and reliability of your application. Security should be part of the design process and not an afterthought applied by administrators trying to secure the system.
The Linux Security and Server Hardening course from INE instructor Muhamad Elkenany will help you understand more about MACL and Linux Security.
Applying a MACL to the application will ensure it has access to exactly what it needs whilst preventing it from having access where it shouldn’t. It can read the beer level in the fridge and place orders to the liquor store, but it cannot spend money elsewhere or access other parts of the system. Your enjoyment of the game on Saturday is assured and your health app on your IoT health scales has no idea of your beverage consumption.