By Bill Graham
Security has quickly risen to the top of mind for embedded developers in the last year. Although the Stuxnet worm was a wake up call for the embedded industry, there have been several other notable incidents since. For example, attackers where able to gain control of a home insulin pump and change its settings. In a recent case in South Houston, Texas, an attacker gained 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. Infrastructure that is increasing more automated and connected, in some cases to the outside world. A fairly large collection of devices, however, is potentially insecure and is the topic for the next series of blogs I’m doing.
Security Best Practices
There are some basic rules and principles that help guide our design and development decisions when building our devices. First and foremost, it’s important to realize that security needs to be built-in rather than tacked-on. Of course, it’s important to improve existing and legacy systems as best you can, but if you’re starting a new project security must be built-in from concept to delivery. It will pay-off considerably down the road.
The following is a list of security best practices (Source “Writing Secure Code” Michael Howard; David LeBlanc, Microsoft Press, 2004) as applied to embedded development.
- Minimize 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 – assigning just enough privilege to an application, task or process to achieve the job at hand. To 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, different devices, software or vendors.
- Secure the weakest link – as with any system, it’s only as good as its weakest component. Similarly for security the most insecure component, interface or application is the most likely avenue of attack.
- Fail-safe stance – expect vulnerabilities to be found, expect physical and remote attacks on the system.
- Assume external systems are insecure – don’t make assumptions about what other devices your product will be connected too. It’s safer to assume that external devices are insecure and that your device is connected to a wide-open network.
- Secure 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 – in general a good design principle. Simpler designs are less likely to have security bugs and vulnerabilities, easier to understand and audit, and easier to test.
It’s important to note that no system is ever completely secure, however 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 should be part of future system designs.
In future posts, I am going to cover recommending the following techniques that align with the best practices above. Here’s a list of things to come:
- Enable a More Secure Configuration – By choosing a more secure configuration, one can remove many of the attack vectors to the device. It’s better to assume your device is going to be attacked and ensure the configuration that your customer receives is more secure “out-of-the-box.”
- Secure Network Communication – It’s safer to assume that all external connections to your device are insecure – proliferation of your device to your customer base may go beyond your perceived use cases. The best practice is to secure all communications in and out of your device.
- Partition Systems to Protect Essential Components – An effective security technique is to separate different major components of a system into partitions. In some cases these partitions are physical, i.e., separate devices now with virtualization technologies these partitions can be virtual, in software, on the same device or processor.
- Harden the System Against Attack – Enabling the security features of your embedded OS is the first step but it’s important to test the system continuously throughout development.
- Secure the Boot and Execution – Securing the boot image is an important step to securing your device. Securing the boot image is an important step to securing your device.
- Secure Data and Data Storage – No assumptions should be made about the classification and privacy of data used in embedded systems. No assumptions should be made about the classification and privacy of data used in embedded systems.
In the final post, I’ll map these recommendations back to the best practices. As you’ll see there are steps that can be taken with existing capabilities of an RTOS like Wind River VxWorks that can improve the security of your devices.
I'd love to hear other examples of security best practices and policies. Please share example of what you're doing to improve your embedded system security.
For additional information from Wind River, visit http://www.facebook.com/WindRiverSystems.