ESF Securing the Software Supply Chain. Recommended Practices for Developers

Description

The ESF Securing the Software Supply Chain - Recommended Practices for Developers is a set of guidelines aimed at improving the security of software development by reducing the risk of supply chain attacks.

The set of recommend principles are framed in 5 top-level sections:

  • Secure product criteria and management

  • Develop Secure Code

  • Verify Third-Party Components

  • Harden the Build Environment

  • Deliver Code

By following these guidelines, software developers can reduce the risk of supply chain attacks and ensure the security and integrity of their software.

Rationale

Historically, software supply chain compromises largely targeted commonly known vulnerabilities organizations that were left unpatched. While threat actors still use this tactic to compromise unpatched systems, a new, less conspicuous method of compromise also threatens software supply chains and undermines trust in the patching systems themselves that are critical to guarding against legacy compromises. Rather than waiting for public vulnerability disclosures, threat actors proactively inject malicious code into products that are then legitimately distributed downstream through the global supply chain. Over the last few years, these next-generation software supply chain compromises have significantly increased for both open source and commercial software products.

Benefits

Supply chain attacks are a type of cyber attack where an attacker infiltrates the software supply chain, often by compromising one of the components used in the software development process, and then uses this access to spread malware or steal sensitive data.

The framework was created to provide software developers with best practices for reducing the risk of supply chain attacks and improving the security of the software development process.

Checkpoints

Does your release confirmation that binaries are digitally signed?

ID

esf_s3c_dev/binaries_signed

Severity

critical

Category

Levels

Optional

false

Tags

cicd-sec-09, cicd-security, releases, security, supply-chain

Description

Does your release confirmation that binaries are digitally signed?

Final packages including the correct metadata should be signed by a cryptographically-secure signature algorithm before being uploaded to the repository.

Rationale

Final packages may be compromised while going through the distribution system from the supplier to the customer. An adversary may attempt a man-in-the-middle attack or compromise the source code repository. As a result, malware or vulnerabilities can be introduced to the package, or an older version of the package containing an exploitable vulnerability can be delivered to the customer. Installing the compromised packages will impose risk to the customer organization and its system.

Verification

This check looks for the following filenames in the project’s last (five) releases: *.minisig, *.asc (pgp), *.sig, *.sign.

Remediation

Generate and publish a signing key, if not done already.

When using raw public keys, i.e. not signed by a trusted Certificate Authority like the X.509 certificate model of 'signing certificates', the problem is: how to ensure that the public key is linked to the owner of the released software?

With PGP public keys, the public key should be downloaded by verifiers either from a trusted site (like organization’s website), or from a keyserver (the signature issues should published the public key on a keyserver and then go to a known keysigning party to become part of the Web of Trust.

  • Publish the release.

  • Download the release as an archive locally.

  • Sign the release archive with this key (should output a signature file).

  • Attach the signature file next to the release archive.

  • If the source is hosted on GitHub, check out the steps here.

The project should not have generated executable (binary) artifacts in the source repository.

ID

esf_s3c_dev/binary_artifacts

Severity

critical

Category

Levels

Optional

false

Tags

security, supply-chain

Description

The project should not have generated executable (binary) artifacts in the source repository, only the source code should be integrated into the build environment.

Rationale

Including generated executables in the source repository increases user risk. Many programming language systems can generate executables from source code (e.g., C/C++ generated machine code, Java .class files, Python .pyc files, and minified JavaScript). Users will often directly use executables if they are included in the source repository, leading to many dangerous behaviors.

Problems with generated executable (binary) artifacts:

  • Binary artifacts cannot be reviewed, allowing possible obsolete or maliciously subverted executables. Reviews generally review source code, not executables, since it’s difficult to audit executables to ensure that they correspond to the source code. Over time the included executables might not correspond to the source code.

  • Generated executables allow the executable generation process to atrophy, which can lead to an inability to create working executables. These problems can be countered with verified reproducible builds, but it seems easier to implement verified reproducible builds when executables are not included in the source repository (since the executable generation process is less likely to have atrophied).

Verification

The check is reported when there is a single binary executable file in the source repository for the project.

Remediation

  • Remove the generated executable artifacts from the repository.

  • Build from source.

Are code check-ins gated by code collaborators and source control to prevent anyone from accidentally or intentionally submitting unreviewed code changes?

ID

esf_s3c_dev/branch_protection

Severity

critical

Category

Levels

Optional

false

Tags

PW.7.2, branch-protection, cicd-sec-01, cicd-security, code-reviews, security, source-code, supply-chain

Description

Are code check-ins gated by code collaborators and source control to prevent anyone from accidentally or intentionally submitting unreviewed code changes?

As part of a check-in process, once of the control is to allow no code that has not been peer or lead reviewed to be checked-in to a source control repository.

Rationale

Fundamental to the protection of the source code repository and its contents are the methods used to control access to it and the validation process used to ascertain whether a check-in is “good.” Access and validation start with good source code management (SCM) principles to track modifications to a source code repository.

Verification

The configuration specifies the minimal protection rules that must be enabled on the configured branches to pass this checkpoint:

  • Prevent force push

  • Prevent branch deletion

  • Status checks defined

  • Have one (or more) reviewers

  • Dismiss stale reviews

Remediation

Follow the instructions to add protected branches rules in GitHub, GitLab or BitBucket.

Please note that in certain special cases the rules may need to be suspended. For example, if a past commit includes illegal or critical content, it may be necessary to use a force push to rewrite the history rather than simply hide the commit.

Small Print

For fetching certain protection rules for branches, this checkpoint may need administrative access to the target repository. If the access token provided does not have administrator role, and the associated protecting rule is required for the checkpoint, the checkpoint will not be given a "pass" state, as the status of protection rule cannot be determined.

Does the team require code reviews for all code and build scripts / configuration changes?

ID

esf_s3c_dev/code_review

Severity

high

Category

Levels

Optional

false

Tags

SSDF-PW.7.2, code-reviews, security, source-code, supply-chain

Description

Does the team require code reviews for all code and build scripts / configuration changes?

This check determines whether the project requires code review before pull requests (merge requests) are merged.

Rationale

Reviews detect various unintentional problems, including vulnerabilities that can be fixed immediately before they are merged, which improves the quality of the code.

Reviews may also detect or deter an attacker trying to insert malicious code (either as a malicious contributor or as an attacker who has subverted a contributor’s account), because a reviewer might either detect the subversion, including any attempts made by the attacker to obfuscate malicious code or implant an evil dependency.

Lack of code review increase the risk of unintentional vulnerabilities or possible injection of malicious code.

Requiring review does not eliminate all risks. The other reviewers might fail to notice unintentional vulnerabilities or malicious code, be colluding with a malicious developer, or even be the same person (using a "sock puppet" account).

Verification

The check first tries to detect whether Branch-Protection is enabled on the default branch with at least one required reviewer or by requiring Approvals from Code Owners. If this fails, the check determines whether the most recent commits have an approved review or if the merger is different from the committer (implicit review). It also performs a similar check for reviews using Prow (labels "lgtm" or "approved") and Gerrit ("Reviewed-on" and "Reviewed-by").

Remediation

  • If the project has only one contributor, or does not have enough reviewers to practically require that all contributions be reviewed, try to recruit more maintainers to the project who will be willing to review others' work. Ideally at least some of these people will be from different organizations (see Contributors checkpoint). If the project has very limited utility, consider expanding its intended utility so more people will be interested in improving it, and make that larger scope clear to potential contributors.

  • Follow security best practices by performing strict code reviews for every new pull request / merge request.

  • Make "code reviews" mandatory in your repository configuration. (Instructions for GitHub.)

Small Print

Requiring reviews for all changes is infeasible for some projects, such as those with only one active participant. Even a project with multiple active contributors may not have enough active participation to be able to require review of all proposed changes. Projects with a small number of active participants instead sometimes aim for a review of a percentage of proposals (e.g., "at least half of all proposed changes are reviewed").

Are all of your builds continuously built and tested?

ID

esf_s3c_dev/continuous_build_test

Severity

low

Category

Levels

Optional

false

Tags

supply-chain, testing

Description

This check tries to determine if the project runs tests before pull requests are merged.

Rationale

Running tests helps developers catch mistakes early on, which can reduce the number of vulnerabilities that find their way into a project.

Verification

The check works by looking for a set of CI-system names in GitHub CheckRuns and Statuses among the recent commits. A CI-system is considered well-known if its name contains any of the following: appveyor, buildkite, circleci, e2e, github-actions, jenkins, mergeable, test, travis-ci.

Remediation

  • Check-in scripts that run all the tests in your repository. Build tools often provide direct support for running tests developed under unit testing frameworks.

  • Integrate those scripts with a CI/CD platform that runs it on every pull request (e.g. if hosted on GitHub, GitHub Actions, Prow, etc).

Small Print

Current implementation is limited to repositories hosted on GitHub and Bitbucket, with other systems under development.

A compliant project using other tools may still receive a low score on this check. There are many ways to implement CI testing, and it is challenging for an automated tool to detect them all. A low score is therefore not a definitive indication that the project is at risk.

Does the project use tools to help update its dependencies?

ID

esf_s3c_dev/dependency_update_tool

Severity

high

Category

Levels

Optional

false

Tags

SSDF-PW.4.4, code-reviews, security, source-code, supply-chain

Description

Does the project use tools to help update its dependencies?

This check tries to determine if the project uses a dependency update tool. These tools automate the process of updating dependencies by scanning for outdated or insecure requirements, and opening a pull request to update them if found.

Rationale

Out-of-date dependencies make a project vulnerable to known flaws and prone to attacks.

There are both open-source and commercial tools available for Software Composition Analysis (SCA) for the process of identifying potential areas of risk from the use of third-party software components.

Dependency Update tools automate part of the dependency-update process by integrating with the SCM, detecting out-of-date or vulnerable dependencies, and creating a pull request with the change in project dependencies descriptors, that could be accepted for merge.

Updates on dependencies should not be done blindly, as they can break the build, introduce bugs or new vulnerabilities, or can be leveraged by attacks on the software supply-chain, when the target component for the update is malicious. Dependency Update tools simplify part of the work, but a thorough review is necessary.

Verification

The check looks for well-known tools in use, specifically dependabot, renovatebot, Depfu, Dependencies.io and Dependaroo.

Remediation

  • Signup for automatic dependency updates with a tool like dependabot or renovatebot, and place the config file in the locations that are recommended by these tools.

For GitHub, see instructions for dependabot or renovatebot.

Small Print

There are many ways to implement dependency updates, and it is challenging for an automated tool to detect them all. A FAIL status is therefore not a definitive indication that the project is at risk.

Do you perform binary composition analysis of the final package?

ID

esf_s3c_dev/final_package_analysis

Severity

high

Category

Levels

Optional

false

Tags

sca, security, supply-chain

Description

Do you perform binary composition analysis of the final package?

Binary software composition analysis tools can investigate what exactly is included in the final deliverables and identify potential issues in the final packages.

Rationale

The final package or update to be delivered to a customer may have issues that expose the developer and customers to cybersecurity and privacy risks. For example, it may contain confidential information (e.g., hard coded credentials, personal data), open source software license issues, and components included in files with unknown origin. Moreover, the deliverable may have been built with improper compiler options or build settings.

Verification

The check looks for automatic scanning of packages in the release pipeline.

Remediation

Ensure automatic scanning of packages for vulnerabilities is enabled at the release branch.

Small Print

Set automatic scanning of packages for vulnerabilities at the release branch.

Do you perform input fuzzing as part of a regular process for your component or product’s inputs?

ID

esf_s3c_dev/fuzzing

Severity

low

Category

Levels

Optional

false

Tags

SSDF-PW.8.2, security, supply-chain, testing

Description

Do you perform input fuzzing as part of a regular process for your component or product’s inputs?

As part of the release readiness criteria a Fuzzing Test should be included.

Rationale

Fuzzing should be performed on all software components during development to ensure that they exhibit expected behavior with different inputs. Results should be documented, and any anomalies or vulnerabilities should be addressed

Verification

This check tries to determine if the project uses fuzzing by checking:

  • if the repository name is included in the OSS-Fuzz project list;

  • if ClusterFuzzLite is deployed in the repository;

  • if there are user-defined language-specified fuzzing functions (currently only supports Go fuzzing) in the repository.

As fuzzers are more relevant for certain languages, the set of languages that should be considered by the check could be configured.

Remediation

  • Integrate the project with the chosen fuzzer.

Example: for OSS-Fuzz over GitHub follow the instructions here.

Small Print

There are many fuzzer tools and ways to run in the build and CI tools, and it is challenging for an automated tool to detect them all. A FAIL status is therefore not a definitive indication that the project is at risk.

Do you perform nightly builds with automated regression and security test to quickly detect problems with recent builds?

ID

esf_s3c_dev/night_builds

Severity

low

Category

Levels

Optional

false

Tags

security, supply-chain, testing

Rationale

To ensure the integrity and quality of the development process, nightly builds should be performed that include manual and automated security and regression tests. Test cases should be implemented during the design of the software and extended during coding to validate all areas of functionality for both “good” and “bad” scenarios. Using this process, any flaws or changes, whether malicious or inadvertent, can be recognized and addressed.

Verification

The check looks for a scheduled pipeline in an hourly time range, that runs a build or compile command.

Please note that other checks verify the execution of security tools of specific types in the pipelines..

Remediation

It is a standard practice to define a nightly build process for daily compiling and testing the software, and when possible to run security analyses to identify known vulnerabilities, secrets leaks, misconfigurations in the build/deployment tools or potential code tampering, etc.

Do you ensure only required modules are included in the product?

ID

esf_s3c_dev/remove_non_require_features

Severity

critical

Category

Levels

Optional

false

Tags

SSDF-PW.7, security, supply-chain

Description

Do you ensure only required modules are included in the product and “unused” modules and code out of scope of the requirements and design document are uninstalled or removed, mitigating “living off-the-land” attacks and decreasing the attack surface?

A project which is not active might not be patched, have its dependencies patched, or be actively tested and used. It might hold possibly unpatched vulnerabilities.

Rationale

It is important that all components and functionality of a product are architected and designed to interact with the system using secure design practices, including threat modeling and attack surface analysis. Once all security risks are identified and mitigated, architecture and design documents are finalized and disseminated to development groups for implementation.

Lowlevel design and functional specifications are created that map directly to the given architecture and high-level design, and development tasks and schedules are mapped out. During the coding and implementation of the system, care must be taken to ensure that all development efforts map to specific system requirements and that there is no “feature creep” that might compromise product integrity or inject vulnerabilities.

Verification

If the project is archived, it receives the lowest score with FAIL compliance.

The activity considered on the project during the previous period (of 90 days by default) is:

  • Commits

  • Changes in issues (including comments) from users who collaborators, members, or owners of the project.

If the activity per week (number of commits or issue changes) exceeds the minimum activity threshold per week, the project receives a PASS with maximum score.

If the activity is below this threshold, the project receives a PARTIAL compliance.

Remediation

There is no remediation work needed from projects not passing this checkpoint. The check simply provides insight into the project activity and maintenance commitment.

External users should determine whether the software is the type that would not normally need active maintenance.

Does the project use a static code analysis tool?

ID

esf_s3c_dev/sast_in_use

Severity

low

Category

Levels

Optional

false

Tags

SSDF-PO.3.1, security, supply-chain, testing

Description

Does the project use a static code analysis tool?

Before the integration of third-party components, each component must be evaluated for the potential security risk that might be associated with it. The evaluation includes reviewing and testing the software.

This check tries to determine if the project uses Static Application Security Testing (SAST), also known as static code analysis.

Rationale

SAST/DAST and other appropriate review such as composition analysis must be performed to determine if the risk is acceptable. Once determined, the source code (not binaries alone) should be integrated into the build environment allowing the security scanning processes of the build environment approved by the organization to take place. Whenever possible, images should be built from the source and not downloaded from the internet, unless there is an understanding of the provenance and trust of delivery.

Lack of SAST increase the risk of unknown bugs (and security vulnerabilities for the security-focused tools) in the delivered software.

Verification

The check looks for execution of known SAST tools in the recent merged PRs, or the usage of these tools in CI workflows.

Remediation

  • Run SAST tool(s) in your CI/CD workflow. Run early and often such tools to catch bugs or security flaws.

Follow the instructions of the particular SAST tool for invocation in the project’s CI workflows.

Small Print

There are many SAST tools and ways of invoking them, and it is challenging for an automated tool to detect them all. A FAIL result is therefore not a definitive indication that the project is at risk.

Do you have and use security tools for Software Composition Analysis?

ID

esf_s3c_dev/sca_in_use

Severity

high

Category

Levels

Optional

false

Tags

sca, security, slsa-4, supply-chain

Description

Do you have and use security tools for Software Composition Analysis?

Rationale

Automatic scanning for vulnerabilities detects known vulnerabilities in packages and dependencies in use, allowing faster patching when one is found. Such vulnerabilities can lead to a massive breach if not handled as fast as possible, as attackers will also know about those vulnerabilities and swiftly try to take advantage of them. Scanning packages regularly for vulnerabilities can also verify usage compliance with the organization’s security policy.

Gathering the dependencies graph and analyzing each dependency for vulnerabilities and other issues is named "Software Composition Analysis" or SCA. Tools that automate such analysis are called SCA tools.

Verification

Ensure automatic dependency scanning for vulnerabilities is enabled.

Remediation

Add dependency scanning tool to pipeline.

Small Print

Requiring reviews for all changes is infeasible for some projects, such as those with only one active participant. Even a project with multiple active contributors may not have enough active participation to be able to require review of all proposed changes. Projects with a small number of active participants instead sometimes aim for a review of a percentage of proposals (e.g., "at least half of all proposed changes are reviewed").

Do you have and adhere to responsible disclosure requirements for all externally identified vulnerabilities?

ID

esf_s3c_dev/security_policy

Severity

low

Category

Levels

Optional

false

Tags

SSDF-RV.1.3, policy, security, supply-chain

Description

Do you have and adhere to responsible disclosure requirements for all externally identified vulnerabilities?

Establish a vulnerability disclosure program, and make it easy for security researchers to learn about your program and report possible vulnerabilities.

Rationale

At some point in the life of any software project, someone (a user, a contributor, or a security researcher) will find a vulnerability that affects the safety and usefulness of the software.

A security policy (typically a SECURITY.md file) can give users information about what constitutes a vulnerability and how to report one securely so that information about a bug is not publicly visible.

Such security policy should document at least:

  • How to contact the project team about a potential security vulnerability.

  • Whether the vulnerability report can be kept private until such time the project decides to share more broadly, after patches are made available.

  • The reporter’s expectations on communication/collaboration around the issue.

  • Kinds of security issues and their corresponding fix / disclosure strategies.

Lack of a publicised security policy may lead to insecure reporting of vulnerabilities, lower trust on project security, public disclosure of vulnerabilities without previous contact with the project team or, as the worst case, vulnerabilities that were discovered but not reported due to lack of security policy, and were later exploited by bad actors.

Verification

This check works by looking for a file named SECURITY.md (case-insensitive) in a few well-known directories.

Remediation

  • Place a security policy file (recommended name: SECURITY.md) in the root directory of your repository. This makes it easily discoverable by a vulnerability reporter.

  • The file should contain information on what constitutes a vulnerability and a way to report it securely (e.g. issue tracker with private issue support, encrypted email with a published public key). You may follow the OpenSSF coordinated vulnerability disclosure guidelines or a similar process to respond to vulnerability disclosures. == Do you use the toolchain to automatically gather information that informs security decision-making?

ID

esf_s3c_dev/sscs_tool_in_use

Severity

high

Category

Levels

Optional

false

Tags

SSDF-PO.4.2, security, supply-chain, testing

Description

Do you use the toolchain to automatically gather information that informs security decision-making?

Use a tool that automate the collection of information about security decision making, the current state and changes that affect security at SDLC supply chain.

Rationale

Software Supply Chain security issues and attacks has been increased as the software release cycles time is reduced due to faster pace of business. A criteria for Secure Software Supply Chain should be define and use as part of the SDLC, in order to support the criteria an automation process to gather and validate current security state and security changes is required to implements that practice at scale and reduce human effort.

Verification

The check looks for execution of known Software Supply Chain Secure (SSCS) tools in the recent merged PRs, or the usage of these tools in CI workflows.

Remediation

  • Run SSCS tool(s) in your CI/CD workflow.

  • Xygeni Scanner is a tool for running scans on software projects, aimed at detecting issues related with the software supply-chain security.

Small Print

There are many SAST tools and ways of invoking them, and it is challenging for an automated tool to detect them all. A FAIL result is therefore not a definitive indication that the project is at risk.

Does your release include an SBOM?

ID

esf_s3c_dev/step_sbom

Severity

high

Category

Levels

Optional

false

Tags

SSDF-PS.3.2, SSDF-PW.4.1, sbom, security, supply-chain

Description

SBOM (Software Bill of Materials) is a file that specifies each component of software or a build process. It should be generated after every pipeline run. After it is generated, it must then be signed. You can configure tools or run commands to check for workflows uses tools to verify this. The parameter are tools and commands.

Rationale

The final package or update to be delivered to a customer may have issues that expose the developer and customers to cybersecurity and privacy risks.

A recommended mitigation is to run a binary scanning or composition analysis tool and ensure the integrity of its product before delivery. The tool can detect potential vulnerabitities and threats, then produce a SBOM of the final package for the customer.

Verification

For each pipeline, ensure it signs the Software Bill of Materials it produces on every run.

Remediation

For each pipeline, configure it to sign its produced Software Bill of Materials on every run.

Do you track all third-party components you use directly and all internal components in a secure and persistent repository?

ID

esf_s3c_dev/use_secure_component_repository

Severity

high

Category

Levels

Optional

true

Tags

SSDF-PS.1.1, SSDF-PW.4.1, security, supply-chain

Description

Do you track all third-party components you use directly and all internal components in a secure and persistent repository?

Both third-party and proprietary components must be stored and consumed from trusted repositories. That repositories should be placed internally if possible and be handle only by administrators.

Rationale

When the organization makes decisions concerning selection, use, changes, or updates of thirdparty or open-source software for its products, it should perform a risk assessment and ensure the residual risks are acceptable.

One key point related to store thirdparty, open source or internally develop components in a secure repository, and all artifacts were analyzed and determined if risk is acceptable before included.

For example, whenever possible, images should be built from the source and not downloaded from the internet, unless there is an understanding of the provenance and trust of delivery, then upload to internal secure repository to be consumed from application lifecycle.

Verification

Initially the check identify untrusted public repositories configure by default, it could be changed in checkpoint configuration file to add other public untrusted repositories, or add in trusted private repositories. When any private repository is declared, the public repository list does not take effect.

Following package managers and repositories are analyzed:

  • Maven

  • Npm

  • Nuget

  • Pip

Remediation

  • Configure untrusted public or trusted private repositories for this check.

  • Remove references to untrusted repositories from project and CI files in following places:

     - Maven repositories referenced in files: pom.xml, settings.xml
     - NPM registry configuration: .npmrc, project configuration, user configuration, global configuration
     - Nuget Package Sources
     - Pip repositories configured in file: requirements.txt