Software Supply Chain Security Best Practices

The software supply chain refers to everything and everyone that is connected to your software code in some way throughout the development lifecycle. Every piece of software is made up of several components. In addition to the proprietary code written from scratch, code also requires external software infrastructure, cloud services, operating systems to work properly. The registries, repositories, codebases, and even the people who wrote this software are all part of the software supply chain.

Each node in this complex chain is a potential point of vulnerability that may impact the performance and security of your software in some ways. Vulnerability introduced at any point along this dependency chain has serious ramifications downstream. That’s because the complexity of the software supply chain masks the risks and makes it difficult to predict and identify without a standardized framework for securing the supply chain. This is why it is important for developers and product organizations to learn what software supply chain security is.

Software supply chain security refers to the set of standardized practices put in place to protect your software from potential vulnerabilities across the software development lifecycle from the point of application development and through continuous integration and deployment (CI/CD pipeline).

It’s important that security teams understand and follow the list of software supply chain security best practices in order to keep their organization’s software supply chain secure. This post details the supply chain best practices that you should know.

Best Practices to Secure Your Software Supply Chain

This section references standard practices developers and product organizations need to follow to secure their software supply chain. You may use these guidelines as a basic framework to describe, assess and measure security practices for your organization within the different stages of your software lifecycle. These best practices cut across the acquisition, development, and deployment phase of the software supply chain to ensure the integrity of your development environment, source code, and final product.

Acquire well-secured components

Incorporating third-party components into software is standard practice for developers, as this allows them to leverage existing API capabilities to deliver desired functionalities instead of building from scratch. Third-party components can either be in the form of commercial proprietary software or free open-source tools. When sourcing either of these components, it is important that you consider security as one of the most important criteria the software component must meet.

To determine the security of third-party components you may need to carry out advanced security analysis such as secure composition analysis, vulnerability database analysis, source code evaluation, and risk assessment analysis. The result of these checks will help determine whether this component is secure and should be allowed for your product

Additionally, selected components need to be monitored continuously using an automated vulnerability tracking service to identify vulnerabilities as soon as possible and remove them promptly.

Create secure software components in-house adhering to secure coding practices

Although external software components incorporated into your software are important, the security and integrity of software products are also dependent on the secure coding practices you follow in-house.

Every organization needs a comprehensive software development lifecycle framework that incorporates secure coding practices to ensure artifacts created are in adherence with stipulated guidelines.

To start with, the integrity of your software products and the artifacts you build in-house depends on the quality of your team. Your development team should include development experts, quality assurance, cybersecurity professionals, and build engineers with a good knowledge of standard security practices.

The product management team should also include security architects, product managers, and product leaders that work to ensure compliance with secure development policies. Some of the basic strategies to ensure that you’re creating secure software artifacts in-house include:

  • Generating design and architecture documents for each artifact
  • Creating threat models for software products
  • Defining and implementing security tests
  • Setting specific release criteria for evaluating product
  • Establishing vulnerability handling policies for each product
  • Documenting and publishing security procedures for each software release

 Use secure third-party software toolchains and compatibility libraries

Many Integrated Development Environments (IDE) used in the software development process are self-contained. This means they allow you to perform various steps within the development process such as coding, compiling, packaging, and debugging code—all from the same tool. Some IDEs also have tools to connect a source to an external repository. IDEs with this function support multiple compiler languages. In addition to these core functions, developers may be able to extend the capabilities of the IDE they use with plugins. This is a potential source of vulnerability for the local development environment, due to the complexity of untrusted sources like this.

In order to keep your development environment secure, all IDEs and plugins to be used within the environment must be audited and pre-approved after being scanned for vulnerabilities and validated.

In addition to plugins that extend the capabilities of your build environment, another category of third-party build tools you may need to check for vulnerabilities is software toolchains and compatibility libraries. These third-party operating system tools are installed on the development environment to allow you to use specific utilities and commands unique to that operating system. For instance, a Windows development environment may require some operating system commands unique to the Linux operating system during the build process in order to provide compatibility between both systems during the production process.

Similarly, API conversion libraries also help you create a common coding environment for two different operating systems. These API toolchains are open-source and commercial tools and they need to be accessed for vulnerabilities before they’re adopted for your build environment and used for your project.

Mitigate modification or exploitation of source code by insiders

According to the Cybersecurity and Infrastructure Security Agency (CISA), an insider is any person with authorized access or knowledge of an organization’s resources. Individuals who have or had access to your facilities, network, equipment, and systems can potentially jeopardize the integrity of your software product, whether intentionally or unknowingly.

As part of efforts to secure your software, you must ensure that the development process has policies in place to prevent intentional or unintentional exposure to malicious code in your production code by insiders such as compromised personnel, poorly trained engineers, or inactive employees. Some of the measures you can put in place to mitigate this include:

  • Balanced and authenticated source code check-in process
  • Automated security scanning for vulnerabilities
  • Secure software development training
  • Hardening the development environment
  • Prioritizing code reviews

Store code or executables and review all changes before approval

Versioning is one of the standard practices that can help maintain the integrity of your software. As part of your Continuous Integration and Deployment process (CI/CD pipeline), you’ll need to maintain a repository to store your code and executables. This provides a working history of your code so you can easily track what has gone into the development stack up to that point.

You’ll also need a continuous approval system to review all changes being made to your software before they’re approved. This is particularly useful when collaborating with other developers within teams. Troubleshooting issues is easier in this instance since you can easily identify changes as they’re being made and who’s making them.

No matter how simple or complex the software you’re building is, a source or version control system makes it easy to see and track all changes being made to your code, track version history when needed, or even revert to an earlier version of your code when necessary.

Create and maintain an SBOM for each software package created

The Software Bill of Materials is vital documentation that details all the third-party components incorporated into your software product. An SBOM makes it easy to validate all approved components of a piece of software and identify any vulnerabilities or defects easily. For every software package you create, you should also create and maintain an SBOM for it.

A Software Bill of Materials can be prepared based on the specifications defined in standard formats such as the Software Package Data Exchange (SPDX), CycloneDX, and Software Identification (SWID) tags as defined by Linux, OWASP, and NIST, respectively.

For every software product you build, the suppliers or owners of the third-party components you use should provide a comprehensive Software Bill of Materials. The deliverables for your project and the SBOMs provided by the supplier can also be validated using a composition analysis (SCA) tool.

Even if the supplier does not provide an SBOM, the SBOM generated with the software composition analysis tool can still provide the required information to describe the third-party components of the software. The process of generating SBOMs should be automated. SBOM automation is vital because the third-party vendors and developers need to generate a new SBOM each time a third-party software is modified, and doing so manually is impractical.The updated SBOM will describe any enhancement or changes in the component code and their relationship with the software product.

Harden the build environment

One of the ways to ensure the integrity of your software is to harden the development environment against potential vulnerabilities. This includes both the individual developer environment and the overall production build environment.

Whether your build environment is hosted in the cloud or on-premise, you need to configure it and put measures in place to secure the server and the network while also controlling who has access to what. Performing due diligence in optimizing and securing the build environment this way will ensure the integrity of your source code and the end product.

Securing the build pipeline involves securing all the systems you use during the build process for your product. This includes code repositories, signing servers, engineering workstations, deployment servers, and so on. Some of the measures you can put in place to secure your build pipeline infrastructure include:

Lock down systems

To secure your systems, you should limit system operations to specific functions that the system is meant to perform. For instance, your build system should only be used for build operations and nothing else.

Limit external and off-LAN network activities

Both inbound and outbound network activities can potentially expose your system to attacks. You should block off all external and off-LAN activities and limit external connections to the necessary URLs.

Monitor systems for data leakages

To ensure the integrity of your product source code, you should set up your cybersecurity defenses to protect your repository, workstation, and other parts of your build environment from the exfiltration and infiltration of data. This involves blocking all malicious behavior, isolating apps, and setting up detection systems to catch any intrusion as soon as they occur.

Configure your version control pipeline

Your code pipeline should be version controlled. In making any changes to your product, updates should be made on the configuration code and not the actual systems.

Multi-factor authentication

Each system that is a part of your build environment should be configured with multi-factor authentication wherever possible. Additional security measures such as role-based access, least privilege and so on should be put in place as well. The NIST guideline also recommends a dual authorization system for all critical or sensitive systems in your build environment.

Segregate your engineering network

Your build system should only be accessed via an isolated engineering network different from the rest of your organization’s network. When possible, the engineering network should be offline.

Analyze each vulnerability to gather sufficient information to plan its remediation

When developing software, measures must be put in place to ensure that your product and all its components are free from known high-risk vulnerabilities. Similarly, when new vulnerabilities are discovered or reported by a customer, you should respond to the incident right away. In some cases, this will require you to update your system to mitigate the risks associated with the newly discovered vulnerability.

Software vendors should have a process in place to accept updates or reports about potential vulnerabilities or defects in their products, either from third-party researchers or customers. You also need to have an automated system that notifies you about vulnerability updates announced by trusted organizations like the Cybersecurity & Infrastructure Security Agency (CISA).

Every organization needs an internal vulnerability management policy that is compliant with standard guidelines. Alerts about high-risk threats should be evaluated based on the relationship between your product and its components that may have been affected by the reported vulnerability. Your engineering team must also have a comprehensive system for reviewing, diagnosing, and possibly resolving issues

Component maintenance

A software product and its components are never static. You should bear in mind that third-party components integrated into your products may be modified or updated by the supplier periodically. You should monitor these modifications especially when they’re related to Common Vulnerabilities and Exposures (CVEs).

A huge part of maintaining your software components is monitoring standard CVE reporting mechanisms and other support channels to determine whether newly identified vulnerabilities in a third-party component incorporated within your product affect the integrity of your own systems and take appropriate actions to mitigate the risks (if any).

When selecting third-party components to be included in your product, you should check the contract to ensure that the owner of the component has policies on how they notify product organizations about updates to their systems, the presence of vulnerabilities, and the timeframe for vulnerability resolution as well as any actions that you may need to perform on your end to ensure optimal security.