Dependency Audit
Intro
Third-party dependencies are the largest part of most codebases'
attack surface. A dependency audit runs the ecosystem's vulnerability
scanner, triages findings by severity, and produces a concrete update
plan.
Overview
Run the right tool
Each ecosystem ships its own audit command:
| Ecosystem |
Audit command |
Outdated check |
| Rust |
cargo audit |
cargo outdated |
| Python |
pip-audit or safety check |
pip list --outdated |
| Node.js |
npm audit or pnpm audit |
npm outdated |
| Go |
govulncheck ./... |
go list -u -m all |
Install the tool if it's missing (e.g. cargo install cargo-audit),
then run it from the project root with the lockfile present.
Triage by severity
- Critical / High — fix immediately. Update or replace the
dependency before merging anything else.
- Medium — schedule a fix within the current sprint.
- Low — track and address when convenient.
For each finding, check whether a patched version exists, whether the
vulnerable code path is actually reached, and whether a workaround
(config, version pin) buys time.
Update strategy
- Update one dependency at a time so breakage is easy to attribute.
- Run the full test suite after each update.
- Read changelogs before any major version bump.
- Use lockfiles to pin exact versions across environments.
Ongoing maintenance
- Schedule monthly dependency reviews on the calendar.
- Enable Dependabot, Renovate, or equivalent for automated update PRs.
- Document any deliberately pinned versions inline with the reason.
Gotchas
Agent-specific failure modes — provider-neutral pause-and-self-check items:
- Running the audit once and never repeating it. Vulnerabilities are added to advisory databases daily. A clean audit today may have critical findings tomorrow. Schedule monthly audits and integrate the scanner into CI.
- Conflating audit with outdated check. The vulnerability scanner (
cargo audit, npm audit) catches known CVEs in current versions. The outdated checker (cargo outdated, npm outdated) flags stale packages. They answer different questions and should both run.
- Auto-merging Dependabot PRs without running tests. A Dependabot PR can introduce a breaking API change even in a patch bump. Require CI to pass and spot-check major bumps manually before merging.
- Treating "0 vulnerabilities" as proof of security. Known-CVE scans miss typosquatting, abandoned maintainers, license risks, and malicious updates. A clean audit is a necessary condition, not a sufficient one.
- Suppressing findings without documenting the reason. Future auditors cannot tell whether a suppressed advisory was intentional or forgotten. Every ignore rule needs a rationale and an expiry date.
- Batching many dependency updates into one PR. When a multi-update PR breaks something, you cannot attribute the breakage to the specific dependency. Update one dependency at a time, run the tests, then merge.
- Treating a major version bump the same as a patch bump. Major bumps require changelog review for breaking changes before merging. A quick major-bump merge is how silent regressions reach production.
Full reference
What "audit" actually checks
Audit tools cross-reference the lockfile against vulnerability
databases (RustSec, OSV, GitHub Advisory, npm advisory). They report
direct and transitive dependencies, but they only catch known
vulnerabilities — a clean audit is not the same as a secure
dependency tree.
When the fix isn't trivial
- No patched version exists. Pin the current version, file an
upstream issue, and look for an alternative library. Document the
acceptance in the lockfile or a
SECURITY.md exception list.
- Patched version is a major bump. Branch off, run the upgrade in
isolation, and address breaking changes before merging.
- Vulnerability is in a transitive dep. Force-resolve the
transitive version (npm
overrides, pnpm overrides, Cargo
[patch], pip constraints) until the parent dependency catches up.
- The vulnerable code path is unreachable in your usage. Note the
rationale alongside the suppression. Do not silently ignore.
Anti-patterns
- Running the audit once and never again.
- Bumping a dozen dependencies in a single PR.
- Suppressing findings without writing down the reason.
- Trusting "0 vulnerabilities" as proof of security — supply-chain
risk extends beyond known CVEs (typosquats, malicious updates,
abandoned maintainers).
- Auto-merging Dependabot PRs without running tests.
Output expectations
A useful audit summary identifies the package manager, lists each
vulnerable dependency with its severity and recommended fix, calls
out anything without a maintained alternative, and proposes a single
ordered update sequence.
1---2name: dependency-audit3description: Audit project dependencies for vulnerabilities and outdated packages. Use when checking the security posture of dependencies, planning updates, or running a pre-release dependency review.4---56# Dependency Audit78## Intro910Third-party dependencies are the largest part of most codebases'11attack surface. A dependency audit runs the ecosystem's vulnerability12scanner, triages findings by severity, and produces a concrete update13plan.1415## Overview1617### Run the right tool1819Each ecosystem ships its own audit command:2021| Ecosystem | Audit command | Outdated check |22|-----------|-------------------------------------|-------------------------|23| Rust | `cargo audit` | `cargo outdated` |24| Python | `pip-audit` or `safety check` | `pip list --outdated` |25| Node.js | `npm audit` or `pnpm audit` | `npm outdated` |26| Go | `govulncheck ./...` | `go list -u -m all` |2728Install the tool if it's missing (e.g. `cargo install cargo-audit`),29then run it from the project root with the lockfile present.3031### Triage by severity3233- **Critical / High** — fix immediately. Update or replace the34 dependency before merging anything else.35- **Medium** — schedule a fix within the current sprint.36- **Low** — track and address when convenient.3738For each finding, check whether a patched version exists, whether the39vulnerable code path is actually reached, and whether a workaround40(config, version pin) buys time.4142### Update strategy4344- Update one dependency at a time so breakage is easy to attribute.45- Run the full test suite after each update.46- Read changelogs before any major version bump.47- Use lockfiles to pin exact versions across environments.4849### Ongoing maintenance5051- Schedule monthly dependency reviews on the calendar.52- Enable Dependabot, Renovate, or equivalent for automated update PRs.53- Document any deliberately pinned versions inline with the reason.5455## Gotchas5657Agent-specific failure modes — provider-neutral pause-and-self-check items:5859- **Running the audit once and never repeating it.** Vulnerabilities are added to advisory databases daily. A clean audit today may have critical findings tomorrow. Schedule monthly audits and integrate the scanner into CI.60- **Conflating audit with outdated check.** The vulnerability scanner (`cargo audit`, `npm audit`) catches known CVEs in current versions. The outdated checker (`cargo outdated`, `npm outdated`) flags stale packages. They answer different questions and should both run.61- **Auto-merging Dependabot PRs without running tests.** A Dependabot PR can introduce a breaking API change even in a patch bump. Require CI to pass and spot-check major bumps manually before merging.62- **Treating "0 vulnerabilities" as proof of security.** Known-CVE scans miss typosquatting, abandoned maintainers, license risks, and malicious updates. A clean audit is a necessary condition, not a sufficient one.63- **Suppressing findings without documenting the reason.** Future auditors cannot tell whether a suppressed advisory was intentional or forgotten. Every ignore rule needs a rationale and an expiry date.64- **Batching many dependency updates into one PR.** When a multi-update PR breaks something, you cannot attribute the breakage to the specific dependency. Update one dependency at a time, run the tests, then merge.65- **Treating a major version bump the same as a patch bump.** Major bumps require changelog review for breaking changes before merging. A quick major-bump merge is how silent regressions reach production.6667## Full reference6869### What "audit" actually checks7071Audit tools cross-reference the lockfile against vulnerability72databases (RustSec, OSV, GitHub Advisory, npm advisory). They report73direct and transitive dependencies, but they only catch known74vulnerabilities — a clean audit is not the same as a secure75dependency tree.7677### When the fix isn't trivial7879- **No patched version exists.** Pin the current version, file an80 upstream issue, and look for an alternative library. Document the81 acceptance in the lockfile or a `SECURITY.md` exception list.82- **Patched version is a major bump.** Branch off, run the upgrade in83 isolation, and address breaking changes before merging.84- **Vulnerability is in a transitive dep.** Force-resolve the85 transitive version (npm `overrides`, pnpm `overrides`, Cargo86 `[patch]`, pip constraints) until the parent dependency catches up.87- **The vulnerable code path is unreachable in your usage.** Note the88 rationale alongside the suppression. Do not silently ignore.8990### Anti-patterns9192- Running the audit once and never again.93- Bumping a dozen dependencies in a single PR.94- Suppressing findings without writing down the reason.95- Trusting "0 vulnerabilities" as proof of security — supply-chain96 risk extends beyond known CVEs (typosquats, malicious updates,97 abandoned maintainers).98- Auto-merging Dependabot PRs without running tests.99100### Output expectations101102A useful audit summary identifies the package manager, lists each103vulnerable dependency with its severity and recommended fix, calls104out anything without a maintained alternative, and proposes a single105ordered update sequence.