SCA / Dependencies
Software Composition Analysis scans the third-party packages you depend on for known vulnerabilities, license issues, and outdated versions. Wire it into CI (npm audit, pip-audit, OSV-Scanner, Snyk, Dependabot, Renovate) and turn the long tail of CVEs into a steady stream of small PRs.
OSV, audit, Renovate, SBOM, SLSA
EXAMPLE
# 1) The pieces of an SCA program
# • Inventory — SBOM (CycloneDX / SPDX)
# • Detection — CVE matching against installed deps (npm audit, OSV-Scanner, Snyk)
# • Remediation — automated PRs (Dependabot, Renovate)
# • Triage — risk-based, not 'fix everything'
# • Verification — re-scan + tests after update
# 2) Quick wins per ecosystem
# Node.js
npm audit
npm audit --omit=dev --audit-level=high
npm audit fix
# Python
pip install pip-audit
pip-audit # against current env
pip-audit -r requirements.txt
# Ruby
bundle audit
bundle audit check --update
# Java
./gradlew dependencyCheckAnalyze # OWASP Dependency-Check plugin
mvn org.owasp:dependency-check-maven:check
# Go
govulncheck ./...
# Rust
cargo install cargo-audit
cargo audit
# Container images
trivy image myapp:1.0
grype myapp:1.0
syft myapp:1.0 -o cyclonedx-json > sbom.json
# Cross-ecosystem (recommended)
brew install osv-scanner # OR install via curl
osv-scanner --lockfile=package-lock.json --lockfile=poetry.lock --lockfile=go.sum --recursive .
osv-scanner --sbom=sbom.json
# 3) GitHub Actions — typical pipeline
name: sca
on:
push:
pull_request:
schedule: [{ cron: '0 6 * * *' }]
jobs:
osv-scanner:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: google/osv-scanner-action@v1
with:
scan-args: |-
-r
--skip-git
--lockfile=./package-lock.json
--lockfile=./poetry.lock
# fails when high-severity findings exist
sbom-and-trivy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: anchore/sbom-action@v0
with: { format: cyclonedx-json, output-file: sbom.json }
- uses: aquasecurity/trivy-action@master
with:
scan-type: sbom
scan-ref: sbom.json
severity: HIGH,CRITICAL
exit-code: '1'
# 4) Dependabot — automatic PRs for outdated deps
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: 'npm'
directory: '/'
schedule: { interval: 'weekly' }
open-pull-requests-limit: 10
groups:
minor-and-patch:
applies-to: 'version-updates'
update-types: ['minor', 'patch']
security:
applies-to: 'security-updates'
update-types: ['major', 'minor', 'patch']
- package-ecosystem: 'docker'
directory: '/'
schedule: { interval: 'weekly' }
- package-ecosystem: 'github-actions'
directory: '/'
schedule: { interval: 'weekly' }
# 5) Renovate — more flexible alternative
# .github/renovate.json
{
"extends": ["config:recommended", ":semanticCommits"],
"vulnerabilityAlerts": { "enabled": true, "labels": ["security"] },
"packageRules": [
{
"matchUpdateTypes": ["minor", "patch"],
"automerge": true,
"automergeType": "pr"
},
{
"matchPackagePatterns": ["*"],
"matchUpdateTypes": ["major"],
"reviewers": ["@security-team"],
"automerge": false
}
],
"schedule": ["before 6am on monday"]
}
# 6) Risk-based triage
# Don't 'fix every CVE'. Prioritise by:
# • EXPLOITABLE in your code path? (not all deps are loaded)
# • CRITICAL with public exploit? (CISA KEV catalog)
# • Direct dependency? (transitive can wait if not exploited)
# • Reachable from public endpoints?
#
# Tools:
# • Snyk Code + Reachability — flags exploitable paths
// • GitHub Code Scanning — combines SCA + SAST findings
// • EPSS scores — probability the CVE is exploited in the wild
// • CISA KEV — vulnerabilities known exploited
# 7) Lock file integrity
# Use commits + 'npm ci' / 'pip install --require-hashes'
# Helps catch supply-chain tampering between scans
# 8) SBOM — Software Bill of Materials
syft dir:. -o cyclonedx-json > sbom.json
syft dir:. -o spdx-json > sbom.spdx.json
# Standard formats:
# CycloneDX — flexible, OWASP-led
# SPDX — Linux Foundation, broad ecosystem support
#
# Some regulations (EU, US Executive Order 14028) require SBOMs.
# Ship one with every release; attach to GitHub releases or your artifact registry.
# 9) SLSA — Supply-chain Levels for Software Artifacts
# Levels 1-4 (low to high) of build / source provenance
# • SLSA 1: scripted build
# • SLSA 2: tamper-resistant builds
# • SLSA 3: hardened, provenance signed
# • SLSA 4: two-person review + reproducible builds
# Use slsa-github-generator for free SLSA 3 provenance with GitHub Actions.
# 10) Container hardening
# • Pin base images by digest (FROM image@sha256:...)
# • Regenerate base images often (weekly nightly rebuild)
# • Use distroless / minimal bases to reduce CVE surface
# • Trivy / Grype scan as a CI gate
# • Image signing: Sigstore / Cosign
# 11) Reachability + dead code
# • Many CVE alerts are unreachable from your code
# • Tools that infer reachability:
// - Snyk Code (per-language)
// - Endor Labs
// - SOOS (per-ecosystem)
# • Cuts triage noise by 60-90% in practice
# 12) License compliance
# SCA tools also flag license issues (GPL in commercial product, copyleft on customer-facing code).
# Set policy: 'no GPL/AGPL in product code' → automated checks reject the dep.
# 13) Patching policy + SLAs
# • Critical (CVSS 9+): patch within 7 days
# • High (7-8.9): patch within 30 days
# • Medium (4-6.9): next release
# • Low: tracked, no SLA
# Track time-to-patch as a metric.
# 14) Common bugs / mistakes
# • Fixing CVEs blindly → breaks the app; tests catch regressions
# • Ignoring transitive dependencies → most CVEs are transitive
# • Stopping at dev deps → some run in CI / build agents
# • Manual updates only → drift; automate with Dependabot/Renovate
# • Not pinning major versions → unexpected breakage on auto-update
# • Container image not rebuilt → base CVEs accumulate; nightly rebuild
# • SCA passes locally, fails CI → different lockfiles; commit + use npm ci
# • Treating SBOM as a one-off → generate per build artifact
# • Suppressing 'noise' permanently — review suppressions quarterly
# • Forgetting NEW deps need a security review — set CODEOWNERS for package.json
Why it matters
SCA = SBOM + vulnerability scan + automated updates + triage. Run OSV-Scanner or your ecosystem’s audit tool in CI, enable Dependabot or Renovate for steady update PRs, prioritise by reachability and CISA KEV (not just CVSS), and produce a CycloneDX SBOM per release so a future CVE is one query away from a known answer.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
// SCA = scan dependencies for known CVEs. // Trivy, Grype, Snyk, GitHub Advisory Database. // Track unfixable CVEs in a risk register.Try it Yourself »
Exercise
Acronym for scanning deps for known CVEs.
Three letters.
Discussion
Loading…