Safety

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: 5

bundle-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