Picking a Winner: How to Pick the Right Dependency (Resolution...- Eve Martin-Jones & Josie Anugerah
Evaluates picking a Winner: How to Pick the Right Dependency (Resolution...- Eve Martin-Jones & Josie Anugerah and evaluates key implications for security practitioners.
Summary
### Overview Eve Martin-Jones and Josie Anugerah from the deps.dev team (part of the Google Open Source Security Team, or GOSST) discuss the hidden complexities of open-source dependency resolution. Analyzing data across package ecosystems including npm, Go, Maven, PyPI, NuGet, and Cargo, the speakers highlight findings from Sonatype's 9th Annual Software Supply Chain Report showing that one in eight open-source downloads has a known risk, and 2.1 billion vulnerable Java components are downloaded monthly—96% of which had an existing fix available. The talk explores why selecting secure dependencies is difficult, revealing that open-source packages rarely have a single deterministic dependency graph, and examines the implications for security practices and standards like Software Bills of Materials (SBOMs).
### Key Topics - **Combinatorial Scale of Dependency Graphs**: Using the npm visualization package D3 as an example, the speakers demonstrate that its 30 direct dependencies and 37 total resolved dependencies can resolve into on the order of 10^81 valid dependency graphs satisfying all constraints. - **Resolution Context and Variables**: Several intentional package management design choices cause dependency graphs to differ dramatically across environments: - *Dependencies in Context vs. Isolation*: Packages are resolved together rather than in isolation. In Pip, conflicting constraints force single-version unification; in npm, multiple versions may be installed side by side. In Maven, an example with package `vert-data` pulling `log4j-core` demonstrates that having four requirements for safe version `2.14.1` and a single plain requirement for `2.0-alpha2` resulted in Maven picking `2.0-alpha2` (vulnerable to Log4Shell) because it was the lowest version specified. - *Time and Update Strategies*: Ecosystems adopting lowest-version strategies (e.g., Maven, Go, NuGet) produce stable graphs, whereas latest-version strategies (e.g., npm, Cargo, Pip) introduce time dependencies where new upstream releases trigger graph changes. In npm and PyPI, deps.dev observed that between a few percent up to 25% of all package versions changed their resolution outcome daily in March. - *Resolver Differences*: Different tools (npm, Yarn, pnpm) or different versions of the same tool (e.g., NuGet altering patch selection rules in v2.8) yield distinct graphs from the exact same manifest. - *Target Architecture and Platform*: Packages like PyPI's TensorFlow distribute wheels tailored to OS and CPU architectures, meaning development on macOS or Windows resolves different dependency trees than production deployments on Linux. - **Limitations of Library SBOMs and Lock Files**: While SBOMs are effective for finalized applications, they fail when published for open-source libraries. A consumer's resolution context (timing, co-dependencies, tool versions, operating system) differs from the library author's context, rendering an author's library-level SBOM irrelevant for assessing downstream consumer risk.
### Technical Details During an illustrative scenario, a maintainer publishes a library with dependencies on packages A and B, producing an SBOM showing zero vulnerabilities. When a downstream consumer incorporates the library alongside package X, time has elapsed: package A has a new release pulling in an indirect dependency C, and package X constrains package B to an older version. The consumer installs a graph that matches virtually none of the versions or components in the author's original library SBOM. Consequently, security and license scans run against a library's SBOM provide a false sense of security. Furthermore, while application lock files capture explicit resolution choices, library lock files are deliberately ignored by package managers to avoid downstream conflicts.
### Takeaways - **Evaluate Dependency Costs**: Apply the same rigor (code review, testing) to third-party dependencies as internal code. Follow principles like the Go proverb ("a little copying is better than a little dependency") and assess whether lightweight alternatives exist. - **Scan What You Ship in Context**: Vulnerability and license scans must be performed on the actual dependency graph deployed in production, not solely in local development environments. - **Align Development and Production**: Keep development environments as close as practicable to production architectures to prevent platform-specific dependency drift. - **Open Requirements vs. Pinned Apps**: Application developers should pin dependencies and maintain lock files, whereas library maintainers should keep requirements open and avoid publishing misleading library-level SBOMs (unless bundling dependencies directly). - **Publish Clear Metadata**: Maintainers should clearly specify authorship, contact information, bug reporting locations, and software licenses to assist ecosystem tooling.
Related talks
The Linux Foundation·36 min
Seth Larson · Python Software Foundation
Explores solving the Phantom Dependency Problem for Python Packages and evaluates key implications for security practitioners.
The Linux Foundation·17 min
Examines bzlmod: Bazels new external dependency system and evaluates key implications for security practitioners.
The Linux Foundation·28 min
Demonstrates driving architectural improvements with dependency metrics and evaluates key implications for security practitioners.


