Co-author: Gopikrishnan Balasubramanian
Every tech company is focusing on IoT and technologies related to it. Whether they are building a Connected Home solution or something on a more grand scale such as Connected Cars or Connected Farms, security is often an afterthought.
Devices such as Firewalls are needed for sure, but security must be built into the system too!
As the world experiences the dangers of malware and the recent ransom-ware attacks, it becomes more important than ever before to build security into the product right from the design stage.
In the rush to build a solution (given the intense competition for time to market), we follow Agile methodologies and that leaves very little room for securing the product towards the end of the lifecycle. This is a primary reason why building security features as part of the product itself, right at the design stage is essential.
The intent of this blog is to give a few useful tips, that would serve as a starting point for product owners and designers, who shoulder the responsibility of ensuring a secure product.
Harden your Linux systems
While the IoT devices themselves may be bought off the shelf and are expected to have basic security controls, the backend servers which usually run on Linux systems need to be secured by the solution provider.
According to Wiki, hardening is usually the process of securing a system by reducing its surface of vulnerability. A system has a larger vulnerability surface the more that it does; in principle, a single-function system is more secure than a multipurpose one.
For instance, a system with multiple interfaces such as USB, Ethernet, Wi-Fi, Bluetooth, and InfraRed interfaces is more vulnerable than a device with just, say an Ethernet interface.
Organizations must have compliance checks to ensure their systems are protected by following the hardening guidelines. Software such as the Linux Kernel, File system, and user applications should be a part of the compliance review.
The philosophy of defensive design is that, if there is a vulnerability or a wrong way to use a product, hackers (or even customers) will find it. Hence the designer of the product must plan for such possibilities.
Designers need to be aware that new threats may arise and new vulnerabilities might be discovered even years after a product has been developed and deployed. So, hardening requirements will also need to change continuously and new patches may need to be applied whenever required.
Principle of Least Privilege
According to experts, any process that runs on a system should run at the minimum privilege level possible.
The Principle of Least Privilege: “Every program and every user of the system should operate using the least set of privileges necessary to complete the job.” (Saltzer and Schroeder, 1975).
For instance, a process can run with root privileges, only if absolutely necessary. This minimizes the risk of a hacker taking control of a process and gaining complete control over the system.
Signing and Secure Boot
In case of an embedded platform, the system must be allowed to load only signed software images from Flash memory. Of course, the bootloader should be configured to verify the signature and it doesn’t fall into the realm of Linux hardening, but, it is important to follow a signing procedure with a signing key to prevent unauthorized images from being flashed on to the platform or being loaded by the bootloader in production mode.
Unless absolutely required, all logging must be disabled on production images. This can be easily achieved with the use of Compile-time flags. If the device needs to be inspected after deployment, a mechanism to store logs internally or securely transmit them to a remote server may be implemented.
External Device connectivity
All ports such as USB and serial ports must be blocked unless it is required to be used by the customer. By default, some of the Kernel configurations may allow connecting USB devices or devices over Wi-Fi or Bluetooth. Such configurations should be disabled.
Each of the Kernel configurations can be inspected and disabled by using the ‘make menuconfig’ command.
Telnet and FTP should be disabled on all production software to prevent unsecured connections to the system. If required, ssh and sftp may be allowed, but they should also be disabled in consumer electronic devices.
Limiting Processes and Access
It is possible that a malware may crash the system by forking itself. Safeguards must be in place to prevent this. One idea is to limit the total number of processes that can run at any point of time by setting the nproc in limits.conf and maximum memory allowed for a particular user.
While not allowing the process to run as root limits its privileges, it is required to ensure that the folders and files (both executables and otherwise) have the least privileges. For example, a non-executable file should not have executable permission. A static file such as an image should not have ‘write’ or ‘executable’ permissions.
Any script that is a part of the Linux system should not access a file using a relative path. All paths must be absolute when accessing a file in the file system.
All binary files must be stripped to remove the debugging and symbol information in the production environment. The strip program removes all unnecessary information from the file and prevents reverse engineering and probable hacking.
It also makes the binary lightweight, thereby freeing up space in a space-constrained embedded platform.
It needs to be carefully evaluated if the IoT system will need to allow hot-plugging of devices. In all cases, if a new device is added to the IoT network, it needs to be authenticated before any data exchange can be performed with the device.
To enforce non-addition of new devices, the /dev hierarchy can be made static and devfs and udev command may be removed. This will prevent hot-plugging of new devices.
Here are some other additional requirements that may be enforced depending on the kind of IoT environment in which the Linux system will be deployed.
- User logins can be disabled in certain systems where no manual intervention or interaction would be required
- Additionally, a further level of protection can be enforced by even prevention of executing shell programs by disabling software such as sh, bash, ksh, ash, and csh, among others
- Data gathered in the IoT environment should be stored in an encrypted format
- No default passwords should be allowed
- No development tools such as compilers, interpreters or debuggers should be installed on the system
- When writing C programs snprintf may be used in place of sprint to prevent a hacker from overrunning the buffer thereby causing a system crash
- It’s also suggested to not use the ‘system’ call to invoke another executable from a C program
- The /etc/inittab should be owned only by root thereby restricting its execution
- Unless absolutely required, some of the Kernel configurations such as the below ones should be disabled:
- SCSI support
- SATA support
This isn’t an exhaustive list by any means and the Kernel Configurations must be enabled/disabled as per the requirements of the IoT system.
Securing the IoT environment, where a number of external devices interact with the system is crucial to prevent DDoS attacks and eavesdropping which results in theft of sensitive data in an IoT environment. While this blog discusses only some of the commonly used mechanisms to harden a Linux system, an extensive analysis and review of requirements for an IoT system must be performed and hardening requirements should be defined accordingly.