Strengthening the Nessus Software Supply Chain with SLSA
You know Tenable as a cybersecurity industry leader whose world-class exposure management products are trusted by our approximately 43,000 customers, including about 60% of the Fortune 500. But sometimes we like to give you a peek behind the curtain to share how we protect our own house against cyberattacks – and that’s what this blog is about. Today we’re sharing our experience adopting the supply-chain security framework SLSA, with the hopes that the lessons we learned will be helpful to you.
As has become crystal clear in recent years thanks to events like Log4j’s Log4Shell vulnerability and the SolarWinds breach, software supply chain security is critical. At Tenable, protecting our software supply chain is a top priority. That’s why last year we took on the challenge of implementing the rigorous Supply-chain Levels for Software Artifacts (SLSA) framework for our Nessus product. Read on to find out why we feel that embarking on our SLSA journey was well worth the effort, and how our team went from SLSA newbies to experts, along the way becoming big believers in the value of this secure development framework.
What is SLSA?
The SLSA framework, developed by Google, is described on its website as a “set of incrementally adoptable guidelines for supply chain security, established by industry consensus.” Its goal? Ensuring the integrity of software artifacts across your entire software supply chain.
“SLSA can be thought of as all the food safety handling guidelines that make an ingredient list credible,” reads SLSA’s website.
“Likewise, the SLSA framework provides this trust with guidelines and tamper-resistant evidence for securing each step of the software production process,” it adds.
Defining some basic terms in the software supply-chain world
Before we proceed, here are some definitions of key terms we’ll be using in this blog:
- CI/CD pipeline: A series of automated steps that facilitate the delivery of new software versions.
- Build system: A system that manages the process of transforming source code into executable binaries or other artifacts.
- Software artifact: Any item produced during software development.
- Source code: Human-readable text written in a programming language.
- Software bill of materials (SBOM): A nested inventory listing the components that make up software.
- Supply chain attack: An attack that targets vulnerabilities in the software supply chain.
- Version control system (VCS): A system that manages changes to source code over time.
Our initial impressions
Once we started the process of implementing SLSA, these characteristics caught our attention:
- Structured trust: SLSA focuses on trust within the parts directly under your control, such as:
- Source code repositories
- Build systems
- Software artifacts
- Version control systems
- Supply-chain confidence: SLSA aims to instill confidence in the build process by verifying each aspect of the build, and protecting it from upstream supply chain attacks. An example of an upstream attack would be if a malicious actor compromises a dependency within the software supply chain. This compromised component is then distributed downstream to other applications or systems.
- You’re on your own, kid: SLSA is just a blueprint. At the time of the implementation, there’s no magic plugin available for our build system or switch to flip that can meet all requirements of SLSA. It will require manual engineering and process changes to produce the artifacts that meet the SLSA specification.
SLSA Level 1
After months of work, we achieved Level 1 adoption of the framework. In a nutshell, this meant producing provenance for a Nessus build. It also meant that we had a scripted build process able to publish a formally structured software-bill-of-materials (SBOM) and a build provenance listing the repository sources and commands executed to build each binary. As a sidenote, we had adopted some of these requirements before starting to implement SLSA, such as using scripted builds and including SBOMs in our builds, which we started doing in 2020.
Let’s look more closely at each one of these elements.
- What does it mean to have a scripted build?
- In our scripted build, all the steps for producing Tenable Nessus are defined by version-controlled build pipelines that invoke build scripts stored in the Nessus repository. These pipelines and build scripts, as well as the documentation for using the build scripts, can be viewed and verified by anyone within Tenable.
- What about the availability of build provenance? :
- This means that we store SBOM attestations to establish and document the provenance of Tenable Nessus builds. Our SBOM is in the OWASP CycloneDX format. The provenance contains the information needed to recreate the build if required, including the source repository tags that the build process uses. It also includes all the parameters used and the configuration steps’ output.
- It also means that our source code is version controlled:
We use a version control system (VCS) to store Nessus source code. By using the VCS, we maintain a record of the history of changes that went into each revision, including:
- Who were the committer and reviewers
- When the reviews and submission occurred
- What changed and why
- What were the parent revisions
The identity of all committers and reviewers is verified via strong authentication. In addition, all contributors must submit a pull request to merge any code. Each version of the source code remains unchanged and is uniquely identified with a permanent reference through the VCS. Tenable Nessus is built from release branches, and we make binaries available for each release.
SLSA Level 1 verification
At Level 1, the focus is on establishing a build provenance to record dependencies and the build commands executed. Here’s how we validate the following:
- Documented build process: Build commands and the SBOM are captured within the provenance file. This is like gathering the recipe and ingredients for a dish you want to cook.
- Provenance file is valid: We double-check that the provenance file is legit. Think of a provenance as a passport. It tells us exactly where our software originated.
- Provenance is stored: We store provenance files that are generated right next to artifacts generated.
Mitigating secret leaks in provenance files
As part of the adoption of these SLSA Level 1 requirements, we encountered a notable challenge that we feel is worth mentioning: The inadvertent exposure of secrets during the provenance collection and compilation is a critical concern. These secrets could include API keys, access tokens, or other confidential data.
To prevent this from happening, we decided to scan provenance files with an automated tool designed specifically for secret detection within source code and configuration files. Specifically, the provenance file is scanned for secrets when it is compiled by the build agent. If a secret is detected, the secret value is replaced with a <Redacted> placeholder. This ensures that recorded build commands, parameters and environment variables recorded will not contain any sensitive information. This proactive approach aligns with the principles of SLSA, emphasizing transparency, trustworthiness and accountability throughout the software supply chain.
SLSA Level 2
Level 2 enhances the tamper resistance during the build process, ensuring that these software artifacts remain unaltered during the build and delivery phases. Here are the key components:
- Build - The importance of using a build service:
- A requirement for SLSA Level 2 is to have all of Tenable's build steps run on a managed build service and not on a developer workstation The build service we use performs the builds, executes services within the pipeline, generates the SBOMs and builds the installers for the application. We don’t run any steps of the build process on developers’ workstations. We strive to carefully manage access to build services. We’ve designed our build system to be as open as possible, so that it can be scrutinized without compromising security.
- Why it’s key to authenticate provenance:
- Authenticating provenance provides verifiable information about the software artifact, including where, when and how we produced it. By ensuring authentic provenance, we achieve two goals: a software consumer can verify the artifact by validating the signature and reproducibility, meaning that the artifact can be rebuilt if needed.
- Another requirement is service-generated provenance:
- We also had to make sure that all Tenable provenance data gets generated directly by the development project’s continuous build and test pipelines, and that users cannot inject or alter the contents of the provenance. Tenable's signatures are generated by an open-source signing service. Other provenance data including the SBOM, cryptographic hashes and build metadata, is outputted by the project build system.
SLSA Level 2 verification
At Level 2, the focus is on ensuring the software we use is reliable, consistent and free of supply-chain tampering. Here’s how we do it:
- Verify the builder:
- Imagine you’re baking a cake. You’d want to know that the person baking your cake is a legit baker, right? Similarly, when building software, we want to make sure that the build process happens in a trusted environment.
- We check that the binary was built by a trusted build agent. Think of this agent as the baker who follows the recipe (your code) to create the final dish (the software).
- Why does this matter? If the build system can’t be trusted, the produced software can’t be trusted.
- Verify the sources:
- Let’s go back to our cake scenario. If you’re baking a cake, you’d want to use fresh ingredients, right? Same goes for software. Verifying the dependencies going into the software is much like making sure your cake ingredients aren’t spoiled before you start baking.
- We ensure that the sources used to build the software come from expected repositories. By verifying the source code comes from a trusted source, it’s like knowing the exact farm your ingredients are sourced from.
- Why? Using spoiled milk to bake a cake will make the end result taste off. Similarly, using dependencies from unknown sources can lead to security vulnerabilities.
- How we do it:
- To verify our builder and sources, we use Rego policies. These are rules we can use to check the recorded provenance to ensure that the sources are correct and the builder is a trusted agent.
- To evaluate the Rego policies, we use a tool called Open Policy Agent (OPA). OPA loads the rego policy and evaluates the provenance to see if everything checks out.
SLSA Level 3
To satisfy the requirements of SLSA Level 3 we needed to harden the build system beyond retaining source code and using a scripted build. We also had to ensure build isolation.
- Retaining source code history:
- For SLSA Level 3, we were required to ensure that all revisions to our source code, along with its change history, are retained indefinitely and can only be deleted by an administrator in compliance with Tenable policy or at the direction of our legal department.
- Scripted build: Another requirement of SLSA is to make sure that the build definition and configuration that are executed by the build server are verifiably derived from text file definitions stored in the VCS.
- Ensure build isolation:
For SLSA Level 3, we also had to make sure that our build service guarantees that every step of the build process takes place in a separate and isolated environment, completely unaffected by other concurrent or previous builds.
Specifically, we had to ensure that access to sensitive information, like the provenance signing key, is prohibited within the build system, as it is stored externally and accessed via a remote connection to a separate system. There can be no possibility for two overlapping builds to impact each other. Each build step occurs in its own isolated machine environment, coordinated by the build system, and these steps are combined using managed pipelines.
In cases where build caches are utilized, we made sure that they are solely content-addressable to prevent any form of tampering. Our ongoing efforts focus on ensuring that one build cannot persist or affect the environment of a subsequent build. We precisely define every aspect of the environment within the build scripts, and this will be guaranteed by conducting builds on ephemeral machines across the board, while also verifying that the results remain identical.
- Guarantee that provenance can’t be falsified:
- Our provenance data is machine generated by the build process, which ensures that it can’t be falsified by any other user. It is also cryptographically signed to prevent tampering. The signing service is not accessible to build-system users or VCS committers.
Controls assessment
In December 2023, Tenable underwent an assessment by a third-party security firm to evaluate the implemented controls for Nessus. As a result, Tenable received an attestation confirming the successful implementation of SLSA Level 3 for Nessus.
SLSA in the Tenable Nessus CI/CD Pipeline
In closing, we hope this blog post proves useful and informative for organizations that are considering adopting the SLSA framework to improve the security of their software supply chain.
Related Articles
- Exposure Management
- Malware & Malicious Behavior
- Risk-based Vulnerability Management
- Vulnerability Management
- Exposure Management
- Risk-based Vulnerability Management
- Security Assurance
- Security Frameworks
- Security Policy
- Vulnerability Management