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).
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
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
orrenovatebot
, and place the config file in the locations that are recommended by these tools.
For GitHub, see instructions for dependabot or renovatebot.
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.
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.
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 |
Description
This check verifies when a build and test job is currently active in pipeline configuration.
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.
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.
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.
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 |
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.
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.
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.
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