Skip to content

Commit

Permalink
Note that pinning is a way to mitigate dependency confusion (#1012)
Browse files Browse the repository at this point in the history
One reason to pin dependencies is that it's one way to
counter dependency confusion attacks; mention that.
Pinning dependencies is definitely not the *only* way, and
it's not even clear it's the best way, but it's a legitimate
reason to pin dependencies in applications.

Signed-off-by: David A. Wheeler <dwheeler@dwheeler.com>
  • Loading branch information
david-a-wheeler committed Sep 14, 2021
1 parent 6fb92a3 commit 6868fe6
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 4 deletions.
4 changes: 1 addition & 3 deletions docs/checks.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,7 @@ The check currently looks for [GitHub packaging workflows]( https://docs.github.
## Pinned-Dependencies

This check tries to determine if the project is an application that has declared and pinned its dependencies. A "pinned dependency" is a dependency that is explicitly set to a specific version instead of allowing a range of versions. If this project is a library (not an application), this check should automatically pass (but see limitations below).
It's important for applications to pin dependencies to ensure that checking and deployment are all done with the same software, reducing deployment risks, simplifying debugging, and enabling reproducibility. In some cases pinning dependencies 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). A risk of pinning dependencies is that it can inhibit software updates (e.g., because of a security vulnerability or because the pinned version is compromised); this can be mitigated by [having applications and *not* libraries pin to specific versions](https://jbeckwith.com/2019/12/18/package-lock/), using automated tools to notify applications when their dependencies are outdated, and by applications that *do* pin dependencies update quickly. Low score is therefore considered `Medium` risk.
It's important for applications to pin dependencies to ensure that checking and deployment are all done with the same software, reducing deployment risks, simplifying debugging, and enabling reproducibility. In some cases pinning dependencies 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). In particular, pinning dependencies is one way to [counter dependency confusion (aka substitution) attacks](https://azure.microsoft.com/en-us/resources/3-ways-to-mitigate-risk-using-private-package-feeds/). In a dependency confusion attack, an application uses multiple feeds to acquire software packages (a "hybrid configuration"), and attackers can fool the user into using a malicious package via a feed that was not expected for that package. A risk of pinning dependencies is that it can inhibit software updates (e.g., because of a security vulnerability or because the pinned version is compromised); this can be mitigated by [having applications and *not* libraries pin to specific versions](https://jbeckwith.com/2019/12/18/package-lock/), using automated tools to notify applications when their dependencies are outdated, and by applications that *do* pin dependencies update quickly. Low score is therefore considered `Medium` risk.
The checks 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) looks for unpinned dependencies in Dockerfiles, shell scripts and GitHub workflows.
*Limitations:* This check should only apply to applications, as libraries shouldn't normally have enforced pinned dependencies. Unfortunately, Scorecard currently can't detect if a project is a library or application. Even when [application detection is added](https://github.com/ossf/scorecard/issues/689), it's always possible for an automated tool like Scorecard to incorrectly categorize software (especially in projects that include both libraries and applications).
You can learn more about dependencies for projects on GitHub using [GitHub dependency graph](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-the-dependency-graph).
Expand Down
8 changes: 7 additions & 1 deletion docs/checks/internal/checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,17 @@ checks:
all done with the same software, reducing deployment risks, simplifying
debugging, and enabling reproducibility.
In some cases pinning dependencies can help
mitigate compromised dependencies
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).
In particular, pinning dependencies is one way to
[counter dependency confusion (aka substitution) attacks](https://azure.microsoft.com/en-us/resources/3-ways-to-mitigate-risk-using-private-package-feeds/).
In a dependency confusion attack, an application uses multiple feeds
to acquire software packages (a "hybrid configuration"),
and attackers can fool the user into using a malicious package
via a feed that was not expected for that package.
A risk of pinning dependencies is that it can inhibit software updates
(e.g., because of a security vulnerability or because the pinned version
is compromised);
Expand Down

0 comments on commit 6868fe6

Please sign in to comment.