The Problem
The principle of code reuse is a foundational axiom of software development. This best practice has manifested itself, in part, in the form of centralized package repositories like Nuget and NPM from which developers can access an entire Internet’s worth of libraries to supplement their code. But when using someone else’s code like this in your projects, you must make sure to also secure your software supply chain.
It is difficult to overstate the value of these repositories. Simple, solved problems can be abstracted away allowing developers to focus on their own business logic. Enterprises can standardize implementations and distribute them to all development teams. The list of advantages goes on and on. They are not, however completely without caveats.
Software teams must be keenly aware that the vast majority of the code they ship is someone else’s code. Any library that becomes a part of the codebase, even if it was written externally, becomes the app team’s responsibility. This means that that along with the value-add of a given package app teams also inherit any security issues that may happen to be present. This issue is of enough concern that Executive Order 14028, May 21, 2021 on improving national cybersecurity has an entire section devoted to securing the software supply chain.
This raises some nontrivial questions about what it means to address this practically:
- How do I know my third-party libraries are secure?
- How can I know which third-party components are in use within my organization?
- What steps can I take to better secure my applications against vulnerable dependencies?
A Solution
There are many established approaches for addressing these concerns that generally tie back to 2 key objective:
- Maintain visibility of the third-party components that ship with all applications.
- Leverage publicly available tools and resources to ensure the version currency and security patch status of those components.
Accomplishing these goals is not as daunting as it may sound. The software industry is gradually centralizing around a small collection of standards for producing SBOM’s (Software Bill of Materials). SBOM’s itemize application dependencies in structured and parse-able formats so that teams can maintain an inventory of their dependencies. Likewise, the tool space for producing SBOM’s continues to grow.
Most widely used package managers also provide inbuilt functionality to identify packages with known vulnerabilities and provide guidance toward upgrading them. For teams requiring more functionality there are also open-source options that leverage public vulnerability databases to provide more a more complete and enterprise-ready experience.
A structured approach to addressing these concerns involves some or all of the following steps:
- Identify and implement tools for maintaining a SBOM leveraging readily available tools.
- Wire SBOM generation into the CD pipeline
- Use the resulting SBOM to make data-driven decisions about what to upgrade and when.
- Provide space within the software development lifecycle (SDLC) for upgrades and regression testing.
These individual steps will vary depending upon the various tools and platforms used by your team to deliver your code. In the following section we will provide specific examples of what such a process can look like.
SDLC Case Study
In this case study we will focus on .NET applications leveraging Nuget for dependency management, along with a JavaScript frontend leveraging npm for dependency management.
Maintaining an SBOM in the CD Pipeline
Microsoft provides an open source SBOM generation tool with detailed instructions for integration with CD pipelines in Github and Azure DevOps. This tool produces SBOMs in the standard CycloneDx format by scanning the build output for known dependencies. The resulting SBOM contains information about file version and also includes file hashes to provide protection against malicious replacement of dependencies. In a later section we will introduce an additional tool that provides a UI for visualizing the dependencies and highlighting any points of concern.
For JavaScript frontends there is also an npm package that provides an SBOM tool. The documentation is lighter for this tool but an approach similar to the one described for .NET would suffice for generating a corresponding npm SBOM.
SBOM Tooling
While teams can certainly roll their own tools for parsing and dealing with the SBOM, there are off-the-shelf solutions that handle this task for you.
OWASP Dependency Track is a flagship OWASP project that provides an API for consuming CycloneDX formatted SBOM’s and a user-friendly web application for identifying outdated and vulnerable packages. Additionally, it leverages several public vulnerability disclosure databases (NVD, Sonatype OSS Index, several others) to ensure up-to-date vulnerability information is available to users.
The project provides a Github action and a Jenkins plugin to simplify interaction with the SBOM ingestion API. However, virtually any system can integrate with the API by wiring a relatively simple cURL command into their CD pipeline similar to the following:
curl -X "POST" "http://dtrack.example.com/api/v1/bom" \
-H 'Content-Type: multipart/form-data' \
-H 'X-Api-Key: LPojpCDSsEd4V9Zi6qCWr4KsiF3Konze' \
-F "project=f90934f5-cb88-47ce-81cb-db06fc67d4b4" \
-F "bom=<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
Leveraging these tools to maintain an up to date SBOM in Dependency Track empowers teams to make informed decisions about what updates are necessary.
SDLC Process Updates
None of these tools can be used to their full potential unless corresponding updates are made to the development process to both review and act upon the results of these scans.
If your team runs on some version of an agile process leveraging a backlog, the simplest solution to this is to ensure that each development effort includes:
- A task to review the SBOM results sometime prior to release.
- A task to remediate any vulnerabilities identified in step 1.
- Regression testing for any components impacted by the upgrades in step 2.
The corresponding workload can obviously vary depending upon the initial tech debt of the application and the frequency with which these actions take place. It may be that your application requires a security-focused sprint to resolve a large portion of tech debt and then ongoing maintenance in future sprints. If your application is relatively up-to-date you may be able to skip directly to the ongoing maintenance.
A reasonable approach would be to set up the tools so that you can accurately gauge the workload and set realistic milestones for remediation. Rarely will two teams accomplish this in exactly the same way, but every step forward is a step in the right direction.
Conclusion
There are many other ways to implement software supply chain assurance, but we hope that the case study above has provided some useful handles for what this might look like in the real world. For many teams, particularly in larger enterprises, it may be preferable to purchase a commercial tool for SBOM management. Several of these are enumerated on the CycloneDX tool center resource.
Regardless of the specific tools chosen for the job, investing in software supply chain security is more than worthwhile. It could be the business control that keeps your company out of the headlines.