Supply Chain Security Begins with Secure Software Development

Image
by Robert C. Seacord

Component-based Software Development

Supply chain security is a complex problem that needs to be solved to before we can gain confidence in the quality of the software systems we depend upon. In July 2001, Addison-Wesley Professional  published the Building Systems from Commercial Components book I coauthored with Kurt Wallnau and Scott Hissam. Building software from commercial and open source software components can dramatically reduce the cost and time required to develop complex business-critical systems. Consequently, this is a widely established practice, and except in rare circumstances, no one is returning to the process of developing proprietary software for the entire software stack. This being said, software developers want to secure their supply chains but don’t know how and software consumers want to understand and limit their exposure to supply chain attacks but have no practical way of doing so.

The software supply chain problem involves understanding what software you are using and the quality attributes (such as modifiability, performance, availability, and security) of this software you are using. Just understanding what software you are using is a significant challenge.

Motivating Example

Let’s imagine you wish to build a collection of microservices for your web application. You might select a Java framework for developing RESTful web services such as Dropwizard,  a NoSQL database such as MongoDBDocker, and the Nginx web server. And of course, we’ll be using a recent version of the Java SDK, such as OpenJDK 11.

At this point, you might imagine you have a pretty good handle on the software components that you are using to build your system, but you would be wrong. Each of these components consists of other subcomponents. For example, Dropwizard uses the Jetty HTTP library to embed an HTTP server directly into your project, the Jersey (the JAX-RS reference implementation) to map HTTP requests to simple Java objects, Jackson for JSON serialization, Logback and slf4j for performant and flexible logging, Hibernate Validator, the JSR 349 reference implementation, for validating user input and generating helpful and i18n-friendly error messages, the Apache HttpClient and Jersey client libraries allow for both low- and high-level interaction with other web services, JDBI to interface with your relational database, Liquibase to keep your database schema in check throughout your development and release cycles, Freemarker and Mustache  templating systems for more user-facing applications, and Joda Time for handling dates and times.

There are more layers of the onion to peel, but let’s just stop here for a second and catch our breath. Clearly, there are many software components to keep track of. Dependencies have dependencies and so forth. It is seldom the case that the developer really knows how deep the dependency tree goes, which software components are being incorporated, the provenance of these components, their versions, and some evidence that these are the actual components and have not been tampered with or trojanized (for example, the SolarWinds.Orion.Core.BusinessLayer.dll digitally-signed component of the Orion software framework containing a back door).

The goal is to produce auditable software artifacts that can be securely and transparently traced back to the original, human readable sources and dependencies. Tools could then be built to analyze these components and identify any policy violations. Additionally, the Supply-chain Levels for Software Artifacts (SLSA) proposal intends to cover a variety of threats, including those posed by the SolarWinds attack.

Software Bill of Materials

Manufacturing faced a similar problem. Their solution was to require a bill of materials (BOM) to provide a comprehensive inventory of the raw materials, assemblies, subassemblies, parts and components, as well as the quantities of each, needed to manufacture a product. The software equivalent is a software bill of materials (SBOM). According to the The National Telecommunications and Information Administration (NTIA) of the US Department of Commerce, a SBOM is effectively a nested inventory, a list of ingredients that make up software components. An SBOM is a directed acyclic graph of software components and information about those components, and supply chain relationships between them.

The NTIA advocates for SBOMs through their Software Component Transparency initiative. NTIA published a Survey of Existing SBOM Formats and Standards in 2019 that references the following standards:

The NTIA survey also identifies related formats such as:

  • CycloneDX is a SBOM standard designed for use in application security contexts and supply chain component analysis.
  • in-toto is a framework to protect the integrity of the software supply chain. It does so by verifying that each task in the chain is carried out as planned, by authorized personnel only, and that the product is not tampered with in transit.
  • and many more.

The in-toto is a framework is being developed under the auspices of the Linux Foundation and is evolving its treatment of integrity and signing capabilities in conjunction with the  tool-to-tool software bill of materials exchange (3T-SBOM). 3T-SBOM is a joint working group of CISQ and the Object Management Group (OMG) focused on the exchange of SBOMs between and among the software development tools that create, revise, manage, orchestrate, and/or otherwise manipulate, assess, or audit software and the 3T-SBOM is merging with the Linux Foundations SPDX efforts to produce a version 3 of that specification with a modular organization to support multiple communities and the nine usage scenarios from 3T-SBOM. The work leverages the efforts of NTIA’s Software Component Transparency initiative.

Attestations

According to SLSA/in-toto, a software attestation is a signed statement (metadata) about a software artifact or collection of software artifacts. An attestation is the generalization of raw artifact/code signing, where the signature is directly over the artifact or a hash of artifact. With raw signing, a signature implies a single bit of metadata about the artifact, based on the public key. With an attestation, the metadata is explicit and the signature denotes who created the attestation. A single keyset can express an arbitrary amount of information, including things that are not possible with raw signing. For example, an attestation might state exactly how an artifact was produced, including the build command that was run and all of its dependencies.

Attestation Model. Author: lodato@google.com licensed under the
Apache License 2.0

Attestations can be used, for example, to identify the provenance of a resource. For example, the following diagram shows that says that the artifact sha256:3c3ff… was built by GitHub Actions from curl/curl-docker@d6525….

Attestation Model. Author: lodato@google.com licensed under the
Apache License 2.0

The curl tool is used as an example because it is a popular open-source package, not to single it out.

Supply-chain Levels for Software Artifacts (SLSA, pronounced salsa) ensures that software artifacts meet certain minimum end-to-end integrity standards. SLSA consists of:

  1. Standards: Industry consensus on the definition of a secure software supply chain. There may be multiple standards to represent multiple aspects of security.
  2. Accreditation: Process for organizations to certify compliance with these standards.
  3. Technical Controls: To record provenance and detect or prevent non-compliance.

Secure Coding Standards

Guaranteeing that a software component is generated from a particular source does not transfer any information concerning the qualities of the source. You may be able to verify the provenance or pedigree of the component using isolated and hermetic builds, but this is a lot of work to protect the integrity of a component with unknown properties.

Image
Garbage <-> Garbage Attestation

Understanding the providence of a software component, such as curl, is inadequate to understand the quality of these components. This is why supply chain security begins with secure software development. The curl tool is primarily written in the C Programming Language. Consequently, it would be useful to know, from a security perspective, that the curl implementation conforms with the requirements of the CERT® C Coding Standard, Second Edition, The: 98 Rules for Developing Safe, Reliable, and Secure Systems, 2nd Edition. Secure coding standards also exist for other languages such as The CERT Oracle Secure Coding Standard for Java and the SEI CERT C++ Coding Standard: Rules for Developing Safe, Reliable, and Secure Systems (2016 Edition). Standards exist for other languages, such as ISO/IEC 5055:2021, Automated source code quality measures, which focuses on detecting and counting violations of good architectural and coding practices in the source code that could result in unacceptable operational risks or excessive costs. For programs written in C, the CERT® C Coding Standard is the most complete of these standards as it has been developed in collaboration with the ISO/IEC JTC1/SC22/WG14 international standardization working group for the programming language C and published along with ISO/IEC TS 17961:2013 C secure coding rules which provides a set of requirements for analyzer vendors. The CERT® C Coding Standard focuses on requirements for software systems developing using C.

Similar to SLSA, there are three levels of conformance to the CERT® C Coding Standard:

CERT C Conformance Levels

Each rule has an assigned priority. Priorities are assigned using a metric based on Failure Mode, Effects, and Criticality Analysis (FMECA). Three values are assigned for each rule on a scale of 1 to 3 for severity, likelihood, and remediation cost.

Emphasis should be placed on conformance Level 1 (L1) rules. Software systems that have been validated as complying with all Level 1 rules are considered to be L1 conforming. Software systems can be assessed as L1, L2, or fully (L3) conforming, depending on the set of rules to which the system has been validated.

To ensure that the source code conforms to this coding standard, it is necessary to have measures in place that check for rule violations. The most effective means of achieving this goal is to use one or more ISO/IEC TS 17961–conforming analyzers. Where a guideline cannot be checked by a tool, a manual review is required.

Coding standards provide a normative set of rules against which software systems can be evaluated. Conforming software systems should demonstrate improvements in the safety, reliability, and security over nonconforming systems. Ultimately, the software consumer decides whom to trust and what standards to enforce.

Accreditation

Accreditation is a means to transfer trust, particularly across organizational boundaries. NCC Group or other third party vendors can analyze a developer’s source code, and assuming the system is non-conforming to a standard, provide a detailed report to guide the code’s repair. After the developer has addressed these findings, NCC Group can retest and provide an attestation of conformance to a coding standard.

A custom predicateType can be used to avoid meaningless boilerplate fields. The following base64-decoded payload Statement is shown below (the outer Envelope looks the same in all cases):

  "_type": "https://in-toto.io/Statement/v0.1",
  "subject": [
    { "digest": { "sha1": "859b387b985ea0f414e4e8099c9f874acb217b94" } }
  ],
  "predicateType": "CERT_C_CONFORMANCE",
  "predicate": {
    "passed": true
    "tester": "mailto:robert.seacord@nccgroup.com",
    "reviewers": ["mailto:bob@nccgroup.com"]
  }
}

Summary

software bill of materials can be used to determine the components that are integrated into your software system and automate the analysis of these components to ensure they comply with policy requirements for the system such as no known open CVEs.

An important part of a secure supply chain is knowing that quality components are used (just like when you buy a car or other manufactured product). Quality assessment can be determined by requiring and then assuring that all software components used in your system conform to a secure coding standard. Oracle, as an example, used conformance to The CERT Oracle Secure Coding Standard for Java to establish the quality of components in their supply chain.

While software bill of materials using the in-toto or other frameworks is not yet a reality, work is continuing and needed to address supply-chain security. Reproducible builds of low-quality code is still garbage in, garbage out, however. Supplementing a SBOM with an attestation of conformance to secure coding standards provides an additional level of assurance about the quality of your components.

Today, NCC Group offers a novel build determinism, pipeline integrity and verification service to identify potential software vulnerabilities within source code or build environments.

Acknowledgements

Thanks to fellow RPI alumnus Bob Martin (MITRE), a current 3T-SBOM chair and Mark Lodato (Google) for reviewing this blog post. Thanks also to Phoebe Queen, Mario Alvarez Iregui, and Jennifer Fernick of NCC Group for their reviews.