A Build Secure Methodology
Over the past several weeks I’ve written two blogs in response to the build into signals coming from the U.S. government, namely the Cybersecurity and Infrastructure Security Agency (CISA). The first describes how the security of intelligent edge systems will evolve. This blog also touches on how build into requirements will play a critical role in improving overall security so companies can focus on true resiliency. The second attempts to delineate the different build into paradigms, or approaches, cybersecurity vendors will take to rally to the government’s call. I’ll now drill down into the third paradigm mentioned in the second blog, Layered Security, and describe Star Lab’s approach.
Let’s start with the graphic to the right. This graphic depicts layers of security that one might employ to protect an intelligent edge system. It is by no means complete, nor does it consider that some layers might not be feasible due to other functional and non-functional requirements. But it is laid out in a deliberate order. It is the order that I want to expand on, and by doing so, provide some instruction on how someone might do this themselves as they consider building in security layers.
Secure (Measured) Boot
Secure or measured boot is at the core of any security implementation. Without secure boot, the rest of the system, even security capabilities, cannot be trusted. I cannot think of single use-case or threat model that would warrant NOT employing secure boot; it is that critical. Fortunately, we’ve already written about secure boot.
Kernel Hardening
Expanding out from the center, security capabilities aimed at the operating system kernel are next to receive attention. Kernel hardening is a simple two-word term that, for the Linux kernel, covers close to sixty possible security configurations that can be used to turn on or off features that reduce your system’s attack surface, make your system less mutable, and activate runtime protections. I would like to say that a single overall security configuration, i.e., a configuration that maximizes security is possible, but it is not. You will need to consider your use-case and threat models to balance security with other functional and non-functional requirements. There are also other kernel-level security solutions that can provide benefit. For example, the use of a Linux Security Module (LSM) like SELinux to monitor and enforce mandatory access controls is often valuable.
Secure Updates
With the secure boot ready and the kernel properly protected, it is now time to consider your system’s update model. Updates can be in the form of an entire system image or updates might be separated into packages for applications, the operating system, the kernel, and possibly firmware. No matter the contents of an upgrade package, it is critical that an update protocol:
Authenticate the sender of an update package;
Validate the contents of an update package have not been modified;
Encrypt the contents of the update package to prevent it from being inspected; and
Implement an approach to revert back to a previous configuration if at any point during the update an error is encountered.
There exists a tension between building a system to be highly immutable and allowing for a system to be easily updated. As part of the build-secure design process, engineers should craft a system update use-case and determine what will be updated, how often the updates are to occur, and whether updates will be delivered remotely or only when the device is physically available. From this use-case, engineers can then design software update procedures that balance security with ease-of-use. These procedures will often include code signatures using cryptographic certificates to ensure the authenticity of the updates as well as possible dedicated secure update servers with least privilege mechanisms being enforced. For external updates, it is also critical to use secure communication channels (HTTPS, SSL/TLS, etc.) to prevent eavesdropping and man-in-the-middle attacks.
Layered Security
With a secure update model designed, it is time to consider the options for creating a layered defense in user-space. From my experience, two of the easiest and most beneficial security integrations are Application Allow-listing and Application Integrity. The former prevents unauthorized file execution while the latter goes a step further to ensure that even if the file is authorized, it has not been modified. This goes a long way to defeating attackers who want to download and execute malware after gaining access.
But how do we limit attackers who exploit vulnerabilities in software? By limit, I mean minimize what the attacker can do upon gaining access. There are several techniques for doing this. First, many capabilities for limiting an attacker are included in the kernel hardening configurations I mentioned before. Essentially, this is the kernel dictating the environment all processes must operate in and setting guardrails for their execution. For example, a kernel hardening configuration might ensure memory reserved for data is always non-executable. Thus, if an attacker attempts to introduce their executable code into a location in memory for data, it will not be allowed to run.
Next, the beforementioned access controls can be a powerful tool for limiting an intruder. If a vulnerability exists in an application, but the application does not have the privileges to modify the configuration of the service the intruder really wants to effect, then the intruder has been limited. Finally, applications can be inspected and / or profiled to devise an understanding of what normal operation looks like. Tripwires can then be set-up that notify an operating system of when a process behaves abnormally. Again, an intruder is limited to camouflaging their malicious behavior to appear as normal; something not easily done or favorable to achieving much.
Whitepaper
Building Security Into Embedded Linux Distributions
Reduced Attack Surface
Finally, don’t forget to reduce your networking attack surface. There are several configurations that should always be used such as DNS over TLS, an adequately configured device firewall, and the deployment of a reliable Intrusion Detection and Prevention System (IDS/IPS). Furthermore, eliminate any unnecessary external interfaces, do your best not to use usernames and passwords to access systems remotely (use certificates and multi-factor authentication instead), and, if possible, attempt to defeat system fingerprinting efforts by not being predictable in the use and configuration of SSH, HTTP(S), RDP, and SMTP.
The above “build-secure” design methodology is obviously described at a high-level. There are nuances to each step described. Most importantly though is to employ a methodology. No one should just use Linux out-of-the-box, nor should they wait to consider important security considerations such as remote update until after a system is designed and built. Furthermore, assume your security posture will need to be fine-tuned to meet other system requirements. You will likely need to adjust your CI/CD environment and possibly introduce security testing as well as performance benchmarking to fine tune your overall system design. Star Lab can help with all of this, and its products are designed to simplify and ease building in security. Contact us if you need assistance.