Dependency Auditing
Keeping the supply chain clean, knowing what your dependencies do and flagging known vulnerabilities.
Overview
Dependency auditing is the practice of scanning third-party libraries for known vulnerabilities (CVEs), malicious code, and supply chain risks. Every npm, RubyGems, PyPI, or Maven dependency is a trust extension; a compromised or malicious package in the dependency tree can exfiltrate credentials, inject backdoors, or corrupt data. npm audit, Bundler-Audit, Trivy, and Snyk are standard tools.
Origin
The npm left-pad incident (2016) demonstrated dependency fragility: a 11-line package removal broke thousands of builds. The event-stream compromise (2018) showed active malice: a maintainer injected cryptocurrency theft code into a popular package. The SolarWinds attack (2020) elevated supply chain security to a national security concern. The US Executive Order 14028 (2021) mandated software bill of materials (SBOM) for government software.
Examples
Automated dependency auditing in CI with npm and Snyk
// .github/workflows/security.yml
// name: Security Audit
// on:
// push:
// branches: [main]
// pull_request:
// schedule:
// - cron: '0 8 * * 1' # Every Monday at 8am
//
// jobs:
// audit:
// runs-on: ubuntu-latest
// steps:
// - uses: actions/checkout@v4
//
// - name: npm audit (fail on high severity)
// run: npm audit --audit-level=high
//
// - name: Snyk vulnerability scan
// uses: snyk/actions/node@master
// env:
// SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
// with:
// args: --severity-threshold=high --fail-on=all
//
// - name: Check for known malicious packages (Socket.dev)
// run: npx @socket.dev/cli@latest scan --org my-org
// package.json: lock exact versions for security-critical packages
const securityDeps = {
'jsonwebtoken': '9.0.2', // exact, not ^9.0.2
'bcryptjs': '2.4.3',
'helmet': '7.1.0',
};Scheduling the audit on a cron (weekly) catches vulnerabilities in unchanged codebases where a CVE was disclosed after the last push. Socket.dev goes beyond CVEs and detects suspicious package behaviour (new install scripts, new network access).
Bundler-audit in Ruby CI pipeline
# Gemfile (add to dev/test group)
# gem 'bundler-audit', require: false
# Rakefile or CI step:
# require 'bundler/audit/task'
# Bundler::Audit::Task.new
# .github/workflows/security.yml
# - name: Update advisory database
# run: bundle exec bundle-audit update
#
# - name: Check for vulnerable gems
# run: bundle exec bundle-audit check --format json | tee audit.json
#
# - name: Fail on high severity
# run: |
# HIGH=$(cat audit.json | jq '[.results[] | select(.criticality == "High" or .criticality == "Critical")] | length')
# if [ "$HIGH" -gt "0" ]; then
# echo "Found high/critical vulnerabilities"
# cat audit.json | jq '.results[] | select(.criticality == "High" or .criticality == "Critical")'
# exit 1
# fi
# Dependabot (automatic PR for gem updates)
# .github/dependabot.yml
# version: 2
# updates:
# - package-ecosystem: bundler
# directory: "/"
# schedule:
# interval: weekly
# open-pull-requests-limit: 5bundle-audit checks against ruby-advisory-db (github.com/rubysec/ruby-advisory-db). Updating the advisory database before running the check (bundle-audit update) is essential; an out-of-date database misses recent CVEs.
Use Cases
- 01CI pipeline gates that block merging when high/critical CVEs are introduced via new or updated dependencies
- 02Weekly scheduled audits that catch vulnerabilities disclosed after the last code change
- 03Software Bill of Materials (SBOM) generation (CycloneDX, SPDX format) for enterprise customers and regulatory compliance
- 04Pre-production approval workflows where security teams review dependency changes before they reach production
When Not to Use
- //Do not ignore audit warnings because they are "only in devDependencies"; postinstall scripts in dev dependencies run in developer environments and can exfiltrate credentials
- //Do not auto-merge major dependency upgrades without testing; security patches sometimes include breaking API changes
- //Do not treat a clean audit as a security guarantee; auditing only covers known CVEs, not zero-days or logic vulnerabilities in dependencies
Technical Notes
- npm audit uses the GitHub Advisory Database (ghsa.github.com) as its source. Snyk and Socket.dev maintain separate databases with different CVE coverage and earlier disclosure for some vulnerabilities
- SLSA (Supply-chain Levels for Software Artifacts, Google 2021) defines four levels of supply chain integrity; Level 3 requires hermetic, reproducible builds and provenance attestation via Sigstore/cosign
- Typosquatting attacks (malicious package names like lodahs for lodash, crossenv for cross-env) are not caught by CVE databases; Socket.dev and NPM registry monitoring detect newly published similar names
- npm package-lock.json records the integrity hash (SHA-512) of every installed package; npm ci verifies these hashes on install, detecting tampering of packages in the registry after initial lock
More in Safety