OpenSSF Scorecards
Description
OpenSSF Scorecards is an automated tool that assesses a number of important heuristics ("checks") associated with software security and assigns each check a score of 0-10. You can use these scores to understand specific areas to improve in order to strengthen the security posture of your project. You can also assess the risks that dependencies introduce, and make informed decisions about accepting these risks, evaluating alternative solutions, or working with the maintainers to make improvements.
Rationale
Scorecards project was created to give consumers of open-source projects an easy way to judge whether their dependencies are safe.
It is not directly targeted for software supply-chain security assessment, but many of its checks are clearly aimed at many of the security issues affecting the supply-chain.
Benefits
Our version generalizes OpenSSF Scorecards project, allowing it to extend to other source code repositories besides GitHub, and working on non-FOSS, commercial software.
The project provides a tool that automates security analysis of open-source projects, helping with decisions based on the security posture of open source projects and with gaining a better understanding of the implications of introducing a dependency on a third-party component.
The public data on scans over the 1 million most critical open source projects are available in a BigQuery public dataset. The scan results may be used to proactively improve the security posture of the critical projects the world depends on.
No Binary Artifacts
ID |
openssf_scorecard/binary_artifacts |
Severity |
critical |
Category |
|
Levels |
|
Optional |
false |
Tags |
security, supply-chain |
Description
Is the project free of checked-in binaries?
The project should not have generated executable (binary) artifacts in the source repository.
Reference: OSSF Scorecard - binary artifacts.
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 checkpoint compliance fails when there is a single binary executable file in the source repository for the project.
Small Print
Many language platforms directly run source code (using interpreters or just-in-time compilers): the source code is executable but reviewable, so it is not considered by this check. This includes shell scripts.
Generated source code, like parsers from parser-generation tools from a grammar specification, or annotated source code that is "transpiled" into generated code, is not considered "binary artifact". Generated source code could be more difficult to review than human-written code (some may argue that there are obfuscation-loving programmers out there), and it is recommended to have the tools for re-generating the code from the initial specification.
Generated documentation in source repositories is also ignored. Generated documentation is intended for use by humans (not computers) who can evaluate the context. Thus, generated documentation doesn’t pose the same level of risk.
Non-executable binary files, like images, videos, and other content, are not considered binary executables for this check.
Branch protection
ID |
openssf_scorecard/branch_protection |
Severity |
critical |
Category |
|
Levels |
|
Optional |
false |
Tags |
branch-protection, cicd-sec-01, cicd-security, code-reviews, security, source-code, supply-chain |
Description
Does the project use branch protection?
This check determines whether a project’s default and release branches are protected with source code repository’s branch protection settings.
Reference: Scorecard Checks page.
Rationale
Branch protection allows maintainers to define rules that enforce certain workflows for branches, such as requiring review or passing certain status checks before acceptance into a main branch, or preventing rewriting of public history.
Different types of branch protection protect against different risks:
-
Require code review: requires at least one reviewer, which greatly reduces the risk that a compromised contributor can inject malicious code. Review also increases the likelihood that an unintentional vulnerability in a contribution will be detected and fixed before the change is accepted.
-
Prevent force push: prevents use of the
--force
option on public branches, which overwrites code irrevocably. This protection prevents the rewriting of public history without external notice. -
Require status checks: ensures that all required CI tests are met before a change is accepted.
To avoid security issues, branch protection rules could be added. These rules provide the following benefits:
-
Avoid unnecessary code commits to the branch
-
Enforce code reviews before merging the code to the branch
-
Maintain a healthy codebase without affecting collaboration
-
Keep commit history (by disallowing force pushes)
-
Makes harder for hardcoded secrets from leaking into (public) repositories
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.
CI Tests: Does the project run tests in CI?
ID |
openssf_scorecard/ci_tests |
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.
Reference: OpenSSF Scorecard - CI Tests.
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. |
OpenSSF Best Practices badge
ID |
openssf_scorecard/cii_best_practices |
Severity |
low |
Category |
|
Levels |
|
Optional |
true |
Tags |
security, security-awareness, security-training |
Description
Does the project have an OpenSSF Best Practices badge?
The Open Source Security Foundation (OpenSSF) Best Practices badge is a way to show that software projects follow recommended best practices, many of them to prevent security issues related to the software supply-chain.
This check determines whether the project has earned a OpenSSF Best Practices Badge, which indicates that the project uses a set of security-focused development best practices for open source software.
Reference: OpenSSF Scorecard - CII-Best-Practices.
Rationale
The OpenSSF Best Practices badge has 3 tiers: passing, silver, and gold. We give full credit to projects that meet the passing criteria, which is a significant achievement for many projects. Lower scores represent a project that is at least working to achieve a badge, with increasingly more points awarded as more criteria are met.
The OpenSSF Best Practices badge has 3 tiers: passing, silver, and gold, with increasing security criteria.
To earn the passing badge, the project MUST:
-
publish the process for reporting vulnerabilities on the project site provide a working build system that can automatically rebuild the software from source code (where applicable)
-
have a general policy that tests will be added to an automated test suite when major new functionality is added
-
meet various cryptography criteria where applicable
-
have at least one primary developer who knows how to design secure software
-
have at least one primary developer who knows of common kinds of errors that lead to vulnerabilities in this kind of software (and at least one method to counter or mitigate each of them)
-
apply at least one static code analysis tool (beyond compiler warnings and "safe" language modes) to any proposed major production release.
Verification
The check uses the URL for the Git repo and the OpenSSF API.
Highest compliance level (and PASS compliance) is given to projects that meet the passing criteria, which is a significant achievement for many projects.
Lower levels (PARTIAL compliance) is given to a project that is at least working to achieve a badge, with increasingly more points awarded as more criteria are met.
FAIL compliance is given to projects that had not enrolled yet with the badge program.
Code Review
ID |
openssf_scorecard/code_review |
Severity |
high |
Category |
|
Levels |
|
Optional |
false |
Tags |
code-reviews, security, source-code, supply-chain |
Description
Does the project require code review before code is merged?
This check determines whether the project requires code review before pull requests (merge requests) are merged.
Reference: OpenSSF Scorecard - Code Review.
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.)
-
Enforce the rule for administrators / code owners as well. (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"). |
Contributors
ID |
openssf_scorecard/contributors |
Severity |
info |
Category |
|
Levels |
|
Optional |
true |
Tags |
source-code |
Description
Does the project have contributors from at least two different organizations?
This check tries to determine if the project has recent contributors from multiple organizations.
Reference: OpenSSF Scorecard - Contributors.
Rationale
This check provides insight into which organizations have contributed, so that a trust-based decision based on that information can be made.
Some projects cannot meet this requirement, such as small projects with only one active participant, or projects with a narrow scope that cannot attract the interest of multiple organizations. See Code Reviews for more information about evaluating projects with a small number of participants.
|
Verification
The check looks at the Company
field on the GitHub user profile for authors of recent commits. To receive the highest score, the project must have had contributors from at least 3 different companies in the last 30 commits; each of those contributors must have had at least 5 commits in the last 30 commits.
Dangerous Workflow
ID |
openssf_scorecard/dangerous_workflow |
Severity |
critical |
Category |
|
Levels |
|
Optional |
false |
Tags |
cicd-sec-04, cicd-security, cicd_code_injection, infrastructure, security, supply-chain |
Description
Does the project avoid dangerous coding patterns in CI workflows?
This check determines whether the project’s GitHub Action workflows has dangerous code patterns. Some examples of these patterns are untrusted code checkouts, logging github context and secrets, or use of potentially untrusted inputs in scripts.
Reference: OpenSSF Scorecard - Dangerous Workflow.
Rationale
Using dangerous coding in CI workflows make the repository vulnerable to compromise. Attackers might access repository secrets or run build scripts controlled by the author of a PR.
Verification
The following patterns are checked:
- Untrusted Code Checkout
-
This is the misuse of potentially dangerous triggers. A well-know example for Github are the
pull_request_target
orworkflow_run
workflow triggers used in conjunction with an explicit pull request checkout. Workflows triggered withpull_request_target
/workflow_run
have write permission to the target repository and access to target repository secrets. With the PR checkout, PR authors may compromise the repository, for example, by using build scripts controlled by the author of the PR, or by reading token in memory. This check does not detect whether untrusted code checkouts are used safely, for example, only on pull request that have been assigned a label. - Script Injection with Untrusted Context Variables
-
This pattern detects whether a workflow’s inline script may execute untrusted input from attackers. This occurs when an attacker adds malicious commands and scripts to a context. When a workflow runs, these strings may be interpreted as code that is executed on the runner. Attackers can add their own content to certain SCM context variables that are considered untrusted, for example,
github.event.issue.title
for GitHub. These values should not flow directly into executable code.
Dependency Update Tool
ID |
openssf_scorecard/dependency_update_tool |
Severity |
high |
Category |
|
Levels |
|
Optional |
false |
Tags |
dependencies, security, 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.
Reference: OpenSSF Scorecard - Dependency Update Tool.
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 or renovatebot.
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.
Fuzzing
ID |
openssf_scorecard/fuzzing |
Severity |
low |
Category |
|
Levels |
|
Optional |
false |
Tags |
security, supply-chain, testing |
Description
Does the project use fuzzing tools?
This check tries to determine if the project uses fuzzing.
Fuzzing tools inject semi-random data into a program to detect bugs. They often use known-to-be-dangerous values (fuzz vectors like random long sequences, extreme values, out-of-bound values, or metacharacters) for each input type, and check the program response.
Reference: OpenSSF Scorecard - Fuzzing.
Rationale
Fuzzing, or fuzz testing, is the practice of feeding unexpected or random data into a program to expose bugs. Regular fuzzing is important to detect vulnerabilities that may be exploited by others, especially since attackers can also use fuzzing to find the same flaws.
For certain languages (C is the archetype) where the memory is managed by the developer, fuzzing can uncover memory-handling and type-mismatch bugs like stack- and heap- overruns, integer overflows, attacks on format strings, off-by-one vulnerabilities…
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.
License Declaration
ID |
openssf_scorecard/license_declared |
Severity |
low |
Category |
|
Levels |
|
Optional |
false |
Tags |
license |
Description
Does the project declare a license?
This check tries to determine if the project has published a license.
Reference: OpenSSF Scorecard - License.
Rationale
A license can give users information about how the source code may or may not be used. The lack of a license will impede any kind of security review or audit, and creates a legal risk for potential users.
Verification
The check looks for a file named according to common conventions for licenses, under standard locations.
This check will detect files in the top-level directory with any combination of the following names and extensions: LICENSE
, LICENCE
, COPYING
, COPYRIGHT
and .html, .txt, .md. It will also detect these files in a directory named LICENSES
. (Files in a LICENSES
directory are typically named as their SPDX license identifier followed by an appropriate file extension, as described in the REUSE Specification.)
This check does not check if usage of third-party dependencies violates their licenses. This is a common feature of Software Composition Analysis (SCA) tools. |
Remediation
-
Determine which license to apply to your project.
-
Create the license in a .txt, .html, or .md file named
LICENSE
orCOPYING
, and place it in the top-level directory. -
Alternately, create a LICENSE directory and add license files with a name that matches your SPDX license identifier.
Maintained
ID |
openssf_scorecard/maintained |
Severity |
critical |
Category |
|
Levels |
|
Optional |
false |
Tags |
security, supply-chain |
Description
Is the project maintained?
This check determines whether the project is actively maintained.
Reference: OpenSSF Scorecard - Maintained.
Rationale
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.
However, a lack of active maintenance is not necessarily always a problem. Some software, especially smaller utility functions, does not normally need to be maintained. For example, a library that determines if an integer is even would not normally need maintenance unless an underlying implementation language definition changed.
A lack of active maintenance should signal that potential users should investigate further to judge the situation.
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.
Packaging
ID |
openssf_scorecard/packaging |
Severity |
high |
Category |
|
Levels |
|
Optional |
false |
Tags |
releases, security, supply-chain |
Description
Does the project build and publish official packages from CI/CD?
This check tries to determine if the project is published as a 'package' or 'deployment unit'.
You can create a 'package' or 'deployment unit' in several ways:
-
Many program language ecosystems have a generally-used packaging format supported by a language-level package manager tool and public package repository.
-
Many operating system platforms also have at least one package format, tool, and public repository (in some cases the source repository generates system-independent source packages, which are then used by others to generate system executable packages).
-
Using container images.
Reference: OpenSSF Scorecard - Packaging.
Rationale
Packages give users of a project an easy way to download, install, update, and uninstall the software by a package manager. In particular, they make it easy for users to receive security patches as updates.
When a project does not distribute updates via a package manager, users may miss security updates.
Other recommendations targeted at improving the security posture of a project against supply-chain attacks seem to contradict this check, as version-pinning is often recommended to avoid unintended injection of malicious, compromised components. Do not confuse the two aspects: Component updates should be easy-to-do but not blindly automatic in general. |
Verification
The check currently looks for CI workflows and language-specific commands that upload the package to a corresponding hub, like Npm or PyPI.
Remediation
-
Publish your project as a downloadable package. This is done typically in a CI workflow that packages the component and publishes it to a component repository or package hub. Follow the instructions for the target, language-specific package manager, for packaging the software assets into a deployable package.
Some SCM platforms have package hubs often used for internal components, but foss components are typically deployed into public language-specific repositories like Npm, PyPI, Maven Central… There are also commercial tools for enterprise software repositories. like the popular SonaType Nexus or JFrog Artifactory.
Example: if the project is hosted on GitHub, use GitHub’s mechanisms for publishing a package. In case you need to publish a package in GitHub package registry, follow the instructions here.
Pinned Dependencies
ID |
openssf_scorecard/pinned_dependencies |
Severity |
high |
Category |
|
Levels |
|
Optional |
false |
Tags |
dependencies, security, slsa-4, supply-chain |
Description
Does the project declare and pin dependencies?
This check tries to determine if the project pins its dependencies. A pinned dependency is a dependency that is explicitly set to a specific one instead of allowing a mutable version or range of versions.
Reference: OpenSSF Scorecard - Pinned Dependencies.
Rationale
Pinned dependencies reduce several security risks:
-
They ensure that checking and deployment are all done with the same software, reducing deployment risks, simplifying debugging, and enabling reproducibility.
-
They can help mitigate compromised dependencies from undermining the security of the project (in the case where you’ve evaluated the pinned dependency, you are confident it’s not compromised, and a later version is released that is compromised).
-
They are one way to counter dependency confusion (aka substitution) attacks, in which an application uses multiple feeds to acquire software packages (a "hybrid configuration"), and attackers fool the user into using a malicious package via a feed that was not expected for that package.
However, pinning dependencies can inhibit software updates, either because of a security vulnerability or because the pinned version is compromised.
Mitigate this risk by:
-
having applications and not libraries pin to specific versions, as described here;
-
using automated tools to notify applications when their dependencies are outdated;
-
quickly updating applications that do pin dependencies.
Remediation
-
First determine if your project is producing a library or application. If it is a library, you generally don’t want to pin dependencies of library users, and should not follow any remediation steps.
-
If your project is producing an application, declare all your dependencies with specific versions in your package format file (e.g.
package.json
for npm,requirements.txt
for python). For C/C++, check in the code from a trusted source and add aREADME
on the specific version used (and the archive SHA hashes). -
If the package manager supports lock files (e.g.
package-lock.json
for npm), make sure to check these in the source code as well. These files maintain signatures for the entire dependency tree and saves from future exploitation in case a package is compromised. -
For Dockerfiles, pin dependencies by hash. See dockerfile for example. If you are using a manifest list to support builds across multiple architectures, you can pin to the manifest list hash instead of a single image hash. You can use a tool like crane to obtain the hash of the manifest list like in this example.
-
For GitHub workflows, pin dependencies by hash. See main.yaml for example. To determine the permissions needed for your workflows, you may use StepSecurity’s online tool by ticking the "Pin actions to a full length commit SHA". You may also tick the "Restrict permissions for GITHUB_TOKEN" to fix issues found by the Token-Permissions check.
-
To help update your dependencies after pinning them, use tools such as dependabot or renovatebot.
SAST in use
ID |
openssf_scorecard/sast_in_use |
Severity |
low |
Category |
|
Levels |
|
Optional |
false |
Tags |
security, supply-chain, testing |
Description
Does the project use static code analysis tools?
This check tries to determine if the project uses Static Application Security Testing (SAST), also known as static code analysis.
Reference: OpenSSF Scorecard - SAST.
Rationale
SAST is analyzing source code before the software is run. This means that the source code can be checked for bugs before it is integrated or complete and ready for delivery.
Using SAST tools can prevent known classes of bugs from being inadvertently introduced in the codebase. Many SAST tools are specialized in catching security flaws; while others are more generic and look for generic defects in source code and configurations.
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.
Security Policy
ID |
openssf_scorecard/security_policy |
Severity |
low |
Category |
|
Levels |
|
Optional |
false |
Tags |
policy, security, supply-chain |
Description
Does the project contain a security policy?
This check tries to determine if the project has published a security policy.
Reference: OpenSSF Scorecard - Security Policy.
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.
-
For GitHub, see more information here.
Signed Releases
ID |
openssf_scorecard/signed_releases |
Severity |
high |
Category |
|
Levels |
|
Optional |
false |
Tags |
cicd-sec-09, cicd-security, releases, security, supply-chain |
Description
Does the project cryptographically sign releases?
This check tries to determine if the project cryptographically signs release artifacts.
A Release Signature is a cryptographic digital signature of a digest of the release contents, that could be verified by consumers of the release (e.g. a tarball) by using the publicly available public key of the signer.
OpenPGP and variants like GnuPG (GPG) are common public key frameworks used for this purpose. Other tools, like minisign, offer popular alternatives for signing the tarball of a release, either in source or in binary form.
There are other tools for digital signatures, like openssl, or code signing certificates (where public keys are signed by a trusted Certificate Authority).
Reference: OpenSSF Scorecard - Signed Releases.
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.
Token Permissions
ID |
openssf_scorecard/token_permissions |
Severity |
critical |
Category |
|
Levels |
|
Optional |
false |
Tags |
infrastructure, security, supply-chain |
Description
Does the project declare tokens in CI/CD as read-only?
This check determines whether the project automated workflows' tokens are set to read-only
by default.
Reference: OpenSSF Scorecard - Token Permissions.
Rationale
Setting token permissions to read-only follows the principle of least privilege. This is important because attackers may use a compromised token with write access to push malicious code into the project.
Verification
The highest compliance level is awarded when the permissions definitions in each workflow’s yaml file are set as read-only at the top level and the required write permissions are declared at the run-level. One point is reduced from the level if all jobs have their permissions defined but the top level permissions are not defined. This configuration is secure, but there is a chance that when a new job is added to the workflow, its job permissions could be left undefined because of human error.
Additionally, points are reduced if certain write permissions are defined for a job.
Under certain SCM platforms like GitHub, the check cannot detect if the "read-only" permission setting is enabled, as there is no API available for that. |
Write permissions causing a small reduction to compliance level:
-
statuses
- May allow an attacker to change the result of pre-submit checks and get a PR merged. -
checks
- May allow an attacker to remove pre-submit checks and introduce a bug. -
security-events
- May allow an attacker to read vulnerability reports before a patch is available. However, points are not reduced if the job utilizes a recognized action for uploading SARIF results. -
deployments
- May allow an attacker to charge repo owner by triggering VM runs, and tiny chance an attacker can trigger a remote service with code they own if server accepts code/location variables unsanitized.
Write permissions causing a large reduction to compliance level:
-
contents
- Allows an attacker to commit unreviewed code. However, points are not reduced if the job utilizes a recognized packaging action or command. -
packages
- Allows an attacker to publish packages. However, points are not reduced if the job utilizes a recognized packaging action or command. -
actions
- May allow an attacker to steal GitHub secrets by approving to run an action that needs approval.
Remediation
For GitHub:
-
Set permissions as
read-all
orcontents: read
as described in GitHub documentation. -
To help determine the permissions needed for project workflows, the StepSecurity online tool could be used, by ticking on "Restrict permissions for GITHUB_TOKEN". You may also tick on "Pin actions to a full length commit SHA" to fix issues found by the Pinned-dependencies check.
Vulnerabilities
ID |
openssf_scorecard/vulnerabilities |
Severity |
high |
Category |
|
Levels |
|
Optional |
false |
Tags |
security, supply-chain, vulnerabilities |
Description
Does the project have unfixed known vulnerabilities?
This check determines whether the project has open, unfixed vulnerabilities.
Vulnerabilities in the third-party dependencies are not analysed by the check. This is the target of Software Composition Analysis (SCA) tools, and of misconfigurations rules in our product. |
Reference: OpenSSF Scorecard - Vulnerabilities.
Rationale
Having unfixed known vulnerabilities increases the risk, proportionally to how much work and expertise are required for a successful exploit of the vulnerability, and its impact on the systems where the software is deployed.
An open vulnerability can be readily exploited by attackers and should be fixed as soon as possible.
Verification
The default configuration for the check uses the Open Source Vulnerabilities (OSV) or NIST National Vulnerabilities Database (NVD) databases. This is relevant for open-source projects.
As private projects typically do not publish detected vulnerabilities in OSV, the check could be configured with a URL pattern plus a 'unfixed vulnerabilities found' response pattern that could help with custom security advisories. But this may not work to detect unfixed vulnerabilities if your security advisories registry does not follow a structured format.
Webhooks
ID |
openssf_scorecard/webhooks |
Severity |
high |
Category |
|
Levels |
|
Optional |
false |
Tags |
cicd-security, infrastructure, security |
Description
Does repository webhooks have a token for authenticating the origin of requests?
Webhooks allow you to build or set up integrations that subscribe to certain events in the project repository. When one of those events is triggered, the webhook’s configured URL will receive an HTTP request with information about the event.
This check determines whether the webhook is secure or not, by taking into account:
-
If a secret token has been configured to authenticate the origins of requests.
-
If the webhook is invoked by using a secure HTTP protocol.
-
If the TLS certificate is validated.
Rationale
If not authenticated, the HTTP payload that your integration will receive could be a faked one generated by a bad actor.
A common way to perform such authentication is to share a secret token that could be registered with the webhook. When the SCM invokes the webhook URL, it sends a header with an message authentication code (MAC) computed over the HTTP payload with the secret token. Your integration should compute the same MAC and compare with the received header. This is documented here for GitHub.
Verification
The behaviour of this detector varies depending on the SCM/ CI/CD system which declares the webhook (- means not supported, x means supported):
-
For GitHub, it looks for Webhooks configured in the project repository. Any webhook without a secret token will make the check FAIL. The same applies for webhooks that do not use a secure HTTP protocol.
-
For CircleCI, the secret token, the
-
For Bitbucket and Azure, just the secure HTTP protocol is checked.
-
For GitLab the verification of the TLS certificate is checked too.
System |
Secret token |
Secure HTTP protocol |
TLS certificate verification |
GitHub |
x |
x |
x |
Bitbucket |
- |
x |
- |
Azure |
- |
x |
- |
GitLab |
- |
x |
- |
CircleCI |
x |
x |
x |
Remediation
-
Check whether your service supports token authentication.
-
If there is support for token authentication, set the secret in the webhook configuration. For GitHub, see webhook secret.
-
If there is no support for token authentication, consider implementing it by following these directions.