# Check Documentation This page contains information on how each check works and provide remediation steps to fix the failure. All of these checks are basically "best-guesses" currently, and operate on a set of heuristics. They are all subject to change, and have room for improvement! If you have ideas for things to add, or new ways to detect things, please contribute! ## Active A project which is not active may not be patched, may not have its dependencies patched, or may not be actively tested and used. So this check tries to determine if the project is still "actively maintained". It currently works by looking for commits within the last 90 days, and succeeds if there are at least 2 commits in the last 90 days. **Remediation steps** - There is *NO* remediation work needed here. This is just to indicate your project activity and maintenance commitment. ## Automatic-Dependency-Update This check tries to determine if a project has dependencies automatically updated. The checks looks for [dependabot](https://dependabot.com/docs/config-file/) or [renovatebot](https://docs.renovatebot.com/configuration-options/). This check only looks if it is enabled and does not ensure that it is run and pull requests are merged. **Remediation steps** - Signup for automatic dependency updates with dependabot or renovatebot and place the config file in the locations that are recommended by these tools. ## Binary-Artifacts This check tries to determine if a project has binary artifacts in the source repository. These binaries could be compromised artifacts.Building from the source is recommended. **Remediation steps** - Remove the binary artifacts from the repository. ## Branch-Protection Branch protection allows defining rules to enforce certain workflows for branches, such as requiring a review or passing certain status checks. This check would work only when the token has [Admin access](https://github.community/t/enable-branch-protection-get-api-without-admin/14197) to the repository. This check determines if the default and release branches are protected. More specifically, the checks for AllowForcePushes (disabled), AllowDeletions (disabled), EnforceAdmins (enabled), RequireLinearHistory (enabled), RequiredStatusChecks (enabled and must have non-empty context enabled), RequiredPullRequestReviews (>=1), DismissStaleReviews (enabled), RequireCodeOwnerReviews (enabled). **Remediation steps** - Enable branch protection settings in your source hosting provider to avoid force pushes or deletion of your important branches. - For GitHub, check out the steps [here](https://docs.github.com/en/github/administering-a-repository/managing-a-branch-protection-rule). ## CI-Tests This check tries to determine if the project runs tests before pull requests are merged. It works by looking for a set of well-known CI-system names in GitHub `CheckRuns` and `Statuses` among the recent commits (~30). A CI-system is considered well-known if its names contains any of the following: appveyor, buildkite, circleci, e2e, github-actions, jenkins, mergeable, test, travis-ci. The check succeeds if at least 75% of successful pull requests have at least one successful check associated with them. **Remediation steps** - Check-in scripts that run all the tests in your repository. - Integrate those scripts with a CI/CD platform that runs it on every pull request (e.g. [GitHub Actions](https://docs.github.com/en/actions/learn-github-actions/introduction-to-github-actions), [Prow](https://github.com/kubernetes/test-infra/tree/master/prow), etc). ## CII-Best-Practices This check tries to determine if the project has a [CII Best Practices Badge](https://bestpractices.coreinfrastructure.org/en). It uses the URL for the Git repo and the CII API. The check does not consider if the repo has a solver or gold levels for passing the test. **Remediation steps** - Sign up for the [CII Best Practices program](https://bestpractices.coreinfrastructure.org/en). ## Code-Review This check tries to determine if a project requires code review before pull requests are merged. First it checks if branch-Protection is enabled on the default branch and the number of reviewers is at least 1. If this fails, it checks if the recent (~30) commits have a Github-approved review or if the merger is different from the committer (implicit review). The check succeeds if at least 75% of commits have a review as described above. If it fails, it does the same check but looking for reviews by [Prow](https://github.com/kubernetes/test-infra/tree/master/prow#readme) (labels "lgtm" or "approved"). If this fails, it does the same but looking for gerrit-specific commit messages ("Reviewed-on" and "Reviewed-by"). **Remediation steps** - Follow security best practices by performing strict code reviews for every new pull request. - Make "code reviews" mandatory in your repository configuration. E.g. [GitHub](https://docs.github.com/en/github/administering-a-repository/about-protected-branches#require-pull-request-reviews-before-merging). - Enforce the rule for administrators / code owners as well. E.g. [GitHub](https://docs.github.com/en/github/administering-a-repository/about-protected-branches#include-administrators) ## Contributors This check tries to determine if a project has a set of contributors from multiple companies. It works by looking at the authors of recent commits and checking the `Company` field on the GitHub user profile. A contributor must have at least 5 commint in the last 30 commits. The check succeeds if all contributor span at least 2 different companies. **Remediation steps** - There is *NO* remediation work needed here. This is just to provide some insights on which organization(s) have contributed to the project and making trust decision based on that. But you can ask your contributors to join their respective organization. ## Frozen-Deps This check tries to determine if a project has declared and pinned its dependencies. It works by (1) looking for the following files in the root directory: go.mod, go.sum (Golang), package-lock.json, npm-shrinkwrap.json (Javascript), requirements.txt, pipfile.lock (Python), gemfile.lock (Ruby), cargo.lock (Rust), yarn.lock (package manager), composer.lock (PHP), vendor/, third_party/, third-party/; (2) look for github actions under .github/workflows/ and verifies they are pinned by hash; (3) looks for Dockerfiles and verifies FROM dependencies are pinned by hash. If one of the files in (1) AND all the dependencies in (2),(3) are pinned, the check succeds. This check does not currently look for shell script pinning (curl | bash) in scripts, Dockerfiles, Makefiles or system()-like code. **Remediation steps** - 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 a `README` 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 the package is compromised. - For Dockerfiles and github workflows, pin dependencies by hash. See example [gitcache-docker.yaml](https://github.com/ossf/scorecard/blob/main/.github/workflows/gitcache-docker.yaml#L36) and [Dockerfile](https://github.com/ossf/scorecard/blob/main/cron/worker/Dockerfile) examples. - To help update your dependencies after pinning them, use tools such as Github's [dependabot](https://github.blog/2020-06-01-keep-all-your-packages-up-to-date-with-dependabot/) or [renovate bot](https://github.com/renovatebot/renovate). ## Fuzzing This check tries to determine if the project uses a fuzzing system. It currently works by checking if the repo name is in the [OSS-Fuzz](https://github.com/google/oss-fuzz) project list. **Remediation steps** - Integrate the project with OSS-Fuzz by following the instructions [here](https://google.github.io/oss-fuzz/). ## Pull-Requests This check tries to determine if the project requires pull requests for all changes to the default branch. It works by looking at recent commits (first page, ~30) and uses the GitHub API to search for associated pull requests. The check discards commits by usernames containing 'bot' or 'gardener'. The check considers a commit containing the string `Reviewed-on` as being reviewed through gerrit; and does not check for a corresponding PR. **Remediation steps** - Always open a pull request for any change you intend to make, big or small. - Make "pull requests" mandatory in your repository configuration. E.g. [GitHub](https://docs.github.com/en/github/administering-a-repository/about-protected-branches#require-pull-request-reviews-before-merging) - Enforce the rule for administrators / code owners as well. E.g. [GitHub](https://docs.github.com/en/github/administering-a-repository/about-protected-branches#include-administrators) ## SAST This check tries to determine if the project uses static code analysis systems. It currently works by looking for well-known results in GitHub pull requests. More specifically, the check first looks for Github apps named [github-code-scanning](https://securitylab.github.com/tools/codeql) (codeql) and sonarcloud in the recent (~30) merged PRs. If >75% of commits contain at least a successful check (by any of the apps above), the check succeeds. If the above fails, the check instead looks for the use of "github/codeql-action" in a github workflow. **Remediation steps** - Run CodeQL checks in your CI/CD by following the instructions [here](https://github.com/github/codeql-action#usage). ## Security-Policy This check tries to determine if a project has published a security policy. It works by looking for a file named `SECURITY.md` (case-insensitive) in a few well-known directories. **Remediation steps** - Place a security policy file `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). ## Signed-Releases This check tries to determine if a project cryptographically signs release artifacts. It works by looking for filenames: *.minisign (https://github.com/jedisct1/minisign), *.asc (pgp), *.sign. for the last 5 GitHub releases. The check does not verify the signatures. **Remediation steps** - Publish the release. - Generate a signing key. - 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. - For GitHub, check out the steps [here](https://wiki.debian.org/Creating%20signed%20GitHub%20releases). ## Signed-Tags This check looks for cryptographically signed tags in the last 5 tags. The check does not verify the signature, but relies on github's verification. **Remediation steps** - Generate a new signing key. - Add your key to your source hosting provider. - Configure your key and email in git. - Publish the tag and then sign it with this key. - For GitHub, check out the steps [here](https://docs.github.com/en/github/authenticating-to-github/signing-tags#further-reading). ## Token-Permissions This check tries to determine if a project's GitHub workflows follow the principle of least privilege, i.e. if the GitHub tokens are set read-only by default. For each workflow yaml file, the check looks for the permissions keyword. If it is set globally as read-only for the entire file, this check succeeds. Otherwise it fails. The check cannot detect if the "read-only" GitHub permission settings is enabled, as there is no API available. **Remediation steps** - Set permissions as `read-all` or `contents: read` as described in GitHub's [documentation](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#permissions).