The average Node.js application has 1,000+ transitive dependencies. The average Python application: 400+. Every one of those dependencies is a potential attack vector that your team did not write, did not review, and may not be monitoring.
OWASP A05 (Vulnerable and Outdated Components) has been in the Top 10 for every edition. The 2025 update expanded it to explicitly include SBOM requirements, reflecting that dependency management has matured from "run npm audit" to a formal supply chain discipline.
The Three Dependency Security Problems
Problem 1: You Don't Know What You Have
Most teams know their direct dependencies (what's in package.json or requirements.txt). Few track transitive dependencies — the dependencies of their dependencies. Yet transitive vulnerabilities account for the majority of CVE exposure.
The Log4Shell vulnerability (CVE-2021-44228, CVSS 10.0) was a transitive dependency for most affected organizations. Teams had no idea they were running Log4j until after the exploit was in the wild.
Solution: Software Bill of Materials (SBOM). A machine-readable inventory of every component in your software, including transitive dependencies, their versions, and their provenance. OWASP CycloneDX and SPDX are the two dominant formats.
# Generate SBOM in CycloneDX format (Node.js)
npx @cyclonedx/cyclonedx-npm --output-format json --output-file sbom.json
# Generate SBOM (Python)
pip install cyclonedx-bom
cyclonedx-py environment --output-format json > sbom.json
Store the SBOM as an artifact of every build. This is the foundation of everything else.
Problem 2: CVEs Are Published Faster Than You Patch
The National Vulnerability Database (NVD) publishes new CVEs daily. For a codebase with 1,000+ transitive dependencies, multiple new CVEs potentially affecting your software are published every week.
A manual workflow — check for vulnerabilities → evaluate severity → create ticket → engineer patches → deploy — has a median time-to-remediate of 60+ days for low/medium vulnerabilities. Critical CVEs should be faster, but many teams don't have the monitoring to detect them in hours.
Solution: Automated CVE feed integration with alerting on new vulnerabilities affecting your dependency inventory.
# GitHub Actions: daily dependency audit
on:
schedule:
- cron: '0 9 * * *' # daily at 9am UTC
push:
paths:
- 'package.json'
- 'package-lock.json'
jobs:
dependency-audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Audit dependencies
run: npm audit --audit-level=high
- name: Check with OSV Scanner
uses: google/osv-scanner-action@v1
with:
scan-args: |-
--lockfile=./package-lock.json
The --audit-level=high flag fails the build for high/critical CVEs. Medium and low create issues without blocking.
Problem 3: Not All CVEs in Your Dependencies Affect You
A CVE in a dependency doesn't automatically mean you're vulnerable. The vulnerability may be:
- In a module you don't use
- Triggered only by specific code paths you don't execute
- Mitigated by your framework or deployment configuration
Automatically treating every CVE as critical leads to alert fatigue. Teams stop responding. Then a genuinely critical, directly exploitable CVE gets buried.
Solution: Exploitability assessment — determine whether the vulnerable code path is actually exercised in your application.
This is partially automated through reachability analysis tools (Snyk, Grype, OSV-Scanner with reachability mode). The tool traces the call graph from your code to the vulnerable function and reports whether the vulnerable code is reachable.
Manual verification is still required for complex cases, but reachability analysis eliminates false positives for most straightforward cases.
Building the SCA Pipeline
A mature dependency security pipeline has four stages:
Stage 1: Inventory (Build Time) Generate SBOM on every build. Store it as an artifact. This is your source of truth.
Stage 2: Scan (CI/CD) Run SCA scan on every PR and every dependency update PR. Block merges for direct dependencies with critical/high CVEs.
- name: Run Grype vulnerability scan
uses: anchore/scan-action@v3
with:
path: "."
fail-build: true
severity-cutoff: high
Stage 3: Monitor (Continuous) Scan the production SBOM daily against updated CVE feeds. Alert security team on new CVEs affecting production components.
The key: the SBOM stays the same between builds. New CVEs against that SBOM are discoverable without rerunning any build.
Stage 4: Remediate (SLA-Driven)
| Severity | SLA |
|---|---|
| CRITICAL (CVSS 9.0+) | 24 hours |
| HIGH (CVSS 7.0–8.9) | 7 days |
| MEDIUM (CVSS 4.0–6.9) | 30 days |
| LOW (CVSS < 4.0) | 90 days |
Track open vulnerability count by age as an operational metric.
Dependency Update Automation
Automated dependency update PRs (via Renovate or Dependabot) reduce the operational burden of staying current:
// renovate.json
{
"extends": ["config:recommended"],
"schedule": ["every weekend"],
"vulnerabilityAlerts": {
"enabled": true,
"schedule": ["at any time"] // security PRs run immediately
},
"packageRules": [
{
"matchUpdateTypes": ["patch"],
"automerge": true // patch updates auto-merge if CI passes
}
]
}
The pattern: security PRs (for known CVEs) open immediately and are prioritized. Minor/patch updates run on weekends and auto-merge if tests pass. Major version bumps require manual review.
SBOM as Compliance Evidence
OWASP Top 10 2025 explicitly lists SBOM generation as a component of A05 (Vulnerable and Outdated Components) compliance. Several regulatory frameworks are moving the same direction:
- Executive Order 14028 (US): Federal contractors must provide SBOM for software delivered to government
- EU Cyber Resilience Act: Products with digital elements must maintain SBOM
- PCI-DSS v4.0: Requirement 6.3.3 — maintain inventory of bespoke/custom and third-party software
Generating and maintaining SBOMs is both a security practice and an emerging compliance requirement. Building the pipeline now means compliance evidence is already available when required.
PentestCheck includes SCA scanning as part of the Deep scan mode, correlating your deployed application's technology fingerprint against CVE databases for externally visible dependency exposure.