Best practices: Improving embedded operating system security
Security has quickly risen to the top of mind for embedded developers in the past year. Although the Stuxnet worm was a wake-up call for the embedded industry, there have been several other notable incidents since.
For example, as reported on CBS News, attackers were able to gain control of a home insulin pump and change its settings with the ability to seriously harm the patient
In a recent case in South Houston, Texas, CNN reported an attacker gaining control of the human machine interface (HMI) of the SCADA system controlling parts of the water treatment plant. In that case, the HMI security consisted of an easily guessed password.
Security is now a top priority for embedded developers because the systems they build can and will be used in critical infrastructure that is increasingly more automated and connected, in some cases to the outside world.
Some classes of devices are already secure because it was a top requirement from their initial concept, for example, communication devices used by the government and military. A majority of devices, however, are potentially unsecure. What is important to realize is that no device is ever completely secure, but developers need to strive to improve the odds through good design, programming, and configuration.
Security Best Practices
There are some basic rules and principles that help guide design and development decisions when building devices (Table 1 below). First and foremost, it’s important to realize that security needs to be built in rather than tacked on. It’s important to improve existing and legacy systems the best way possible, and new projects should have security built in from day one. It will pay off considerably down the road.
The following is a list of security best practices (source: Writing Secure Code by Michael Howard and David LeBlanc,, 2004) as applied to embedded development:
* Minimizing the attack surface: Reduce the number of attack vectors into the system. Turn off features, services, and access not necessary for most users.
* Least privilege: Assign just enough privilege to an application, task, or process to achieve the job at hand. Too high a privilege level allows for unwanted access or behavior.
* Defense in depth: Rely on more than one layer of defense and don’t count on any one layer as providing complete protection.
* Diversity in defense: Use different types of defense devices, software, or vendors.
* Securing the weakest link: Secure the most unsecure component, interface, or application, the most likely avenue of attack; because any system is only as good as its weakest component.
* Fail-safe stance: Expect vulnerabilities to be found; expect physical and remote attacks on the system.
* Assumptions about external systems: Avoid assumptions about other devices your product will be connected to. You can’t assume external devices are secure, and be aware that your device is connected to a wide-open network.
* Security by default: Set the default configuration and behavior of the system to be as secure as possible. Turn off features, services, and access not necessary for most users.
* Simplicity and usability: Use simpler designs that are less likely to have security bugs and vulnerabilities and are easier to understand, audit, and test.
It’s important to note that no system is ever completely secure. However, as we shall see later in this article, there are practical steps that can be followed that dramatically improve security for embedded systems. In some cases, these techniques can be applied to existing systems; in other cases, they are proposals for future system designs.