Secure Software Development Build System
- Architecture & Design Review – security risk mitigation starts with design. There is no architectural design that can be perfectly secure, but the architectural choices you make up front can negatively or positively impact the security profile of your application. Designing with a zero trust model in mind is a good starting point.
- Software Threat Modeling – threats exist at every stage of the SDLC, including during the import of third-party code, the build systems used to create software artifacts, and the mechanisms whereby software, updates and patches are delivered. DevSecOps in general, and security architects in particular should develop threat models for all critical components and systems in the build pipeline and review them on a regular basis.
- Coding Standards – standard coding best practices apply for development teams, including code reviews that incorporate peer review by at least two developers before any code can checked into a code repository that must support Multi-Factor Authentication (MFA). Multiple code branches should be used, such as development, test and production, with appropriate criteria enforced when moving code between each branch.
- Secure Library Checks – incorporate only third-party/open source libraries that have been vetted by your organization. Ensure the use of dedicated systems to download, scan, and perform recurring checks of third-party/open source libraries for new versions, updates, and known/newly reported vulnerabilities.
- Code & Executable Testing – QA testers should incorporate both Static analysis and Dynamic Application Security Testing (SAST and DAST), as well as Software Composition Analysis (SCA) tools to identify issues and vulnerabilities in proprietary and third-party code. QA methodologies should feature regular penetration testing, OWASP “top 10” testing (for web applications), timely fixing of security defects, and documenting the Common Vulnerability Scoring System (CVSS) scores for all software analyzed.
- Secure Build & Delivery – harden the application development, build and delivery environments, and ensure all software is developed following secure software development practices (such as proposed by the Supply-Chain Levels for Software Artifacts, or SLSA security framework) as attested to by a software attestation. All relevant artifacts must be identified via an SBOM, signed, and stored for future reference.
But even once a secure application is released, automated initiatives must be in place to track vulnerabilities in order to ensure customers can be provided with timely notifications and security updates.
Securing the Software Build Process
The software build process incorporates:
- Proprietary code
- Third-party code
- The build system itself
Special attention should be paid to securing the third-party components that comprise >80% of the code in most modern applications, including free libraries, open source dependencies, and Commercial Off The Shelf (COTS) software. Best practices for securing the software supply chain starts when importing third-party code:
- All imported components must be scanned on download for malware, trojans, backdoors, and other malicious code/security issues. Traditional static code analysis tools are key, but you may also want to check against typosquatting, as well.
- A “quarantine repository” is recommended where components can be further analyzed to ensure security and integrity. This is where security vulnerabilities should be identified, as well as a plan to address them. Some enterprises may want to perform further checks, such as license checks in order to ensure compliance with corporate guidelines. Before moving components to an artifact repository for developer access, organizations should check the originating ecosystem to ensure it hasn’t been identified as compromised. For example, most open source ecosystems will quickly remove malicious packages from their public repository.
- Finally, components should be moved to an artifact repository, which is the only repository developers should be granted access to when it comes to incorporating third-party components into the codebase. This repository should provide continuous vulnerability scanning, vulnerability status, and automated notifications when a vulnerability is found. Notifications should also include patch/upgrade recommendations.
Special attention should also be given by DevOps to the build system itself. A secure build system starts with the realization that nothing in the enterprise should be built as a one-off artifact on a developer’s machine. Rather, software build systems must be treated like factory assembly lines: fully automated from start to finish. Automation is key to connecting all the steps in the process in a deterministic way.
The Supply chain Levels for Software Artifacts (SLSA) specification is a secure software development framework originally proposed by Google and now driven by a consortium of industry leaders. It provides a check-list of standards and controls to prevent tampering, while improving the integrity and security of software artifacts created by any build system.
For example, a secure build service is one that is a dedicated service that runs on a minimal set of predefined, locked down resources rather than a developer’s desktop or other arbitrary system that can offer a larger attack surface to hackers. It typically includes features such as:
- Build Steps – each build step should have a single responsibility, such as retrieving source code, building an artifact, etc. When that responsibility is fulfilled, the output is checked and, if required, passed to the next step.
- Infrastructure – all build steps should have dedicated resources, such as a hardened container in which to execute. Once the step is complete, all those resources should be discarded, preventing contamination of subsequent steps.
- Environments – each build step requires an environment in which to run. Care must be taken to ensure the runtime environment is minimized, and the container only includes components that are absolutely required (such as compilers) in order to shrink the attack surface.
- Provenance – each build must be dependency complete, and each dependency traceable to the originating source. An out-of-band Software Bill Of Materials (SBOM) should be produced for independent verification.
- Service/Network – creating a dedicated build service that runs on a segmented network with no internet or manual access will limit local exploits and remote tampering/intrusion. This means:
- Scripted Builds – build scripts cannot be accessed and modified within the build service, preventing exploits.
- Ephemeral, Isolated Build Steps – every step in a build process executes in its own container, which is discarded at the completion of each step. In other words, containers are purpose-built to perform a single function, reducing the potential for compromise.
- Hermetic Environments – containers have no internet access, preventing (for example) dynamic packages from including remote resources.
- Reproducible Builds – the build process fails safe, terminating the build if any component generated during a build step fails its checksum verification.
The result should be a verifiably reproducible build, where not only do the same inputs produce the same outputs every time, but whose provenance can also be verified by tracing each component back to its original source.
Finally, risk management best practices should be enforced. For example, the build system processes and infrastructure should be subject to auditing on a regular basis to ensure that it continues to fulfill its original purpose and has not been compromised.