Dependency Audit — Framework, Package, and Toolchain Security
Audit project dependencies, frameworks, language runtimes, and dev tools for known vulnerabilities (CVEs), security anti-patterns, and supply chain risks.
Methodology
Step 1: Inventory the Stack
Identify everything in use — not just direct dependencies but the full chain:
Package manifests — read and catalog:
Node/JS: package.json, package-lock.json, yarn.lock, pnpm-lock.yaml
Python: requirements.txt, Pipfile.lock, pyproject.toml, poetry.lock
Ruby: Gemfile, Gemfile.lock
Go: go.mod, go.sum
Rust: Cargo.toml, Cargo.lock
Java: pom.xml, build.gradle
PHP: composer.json, composer.lock
.NET: *.csproj, packages.config
Framework and runtime versions:
- Check framework version (Next.js, Django, Rails, Spring, Laravel, Express, etc.)
- Check language/runtime version (Node.js, Python, Ruby, Go, Java, PHP, .NET)
- Check infrastructure tools (Docker base images, Terraform providers, Kubernetes versions)
Dev tools and CI/CD:
- Check CI/CD pipeline configs (.github/workflows, .gitlab-ci.yml, Jenkinsfile)
- Check pre-commit hooks, linters, formatters
- Check container base images and their update status
- Check IaC tool versions (Terraform, Pulumi, CDK)
Edge cases in package manifests:
optionalDependencies — installed but not audited by default
peerDependencies — version range may not match what's installed
overrides / yarn resolutions / pnpm overrides — check if used to silence advisories rather than fix them
- Monorepos: read every
packages/*/package.json and apps/*/package.json, not just the root
engines field — older-than-LTS Node makes other audits moot
Step 2: Run Automated Audit Tools
Run the appropriate audit command for the project:
# Node.js
npm audit --json # full structured output
npm audit --omit=dev --json # production-only: filters dev/build-time vulns
# Compare the two — vulns only in dev/build tooling do not ship to users
# and should be triaged as lower priority. Don't bury this in the report.
# Python
pip audit # If pip-audit installed
safety check # If safety installed
# Ruby
bundle audit
# Go
govulncheck ./...
# Rust
cargo audit
# PHP
composer audit
# .NET
dotnet list package --vulnerable
# Docker
docker scout cves <image>
trivy image <image>
# General (if Trivy is available)
trivy fs .
Applying fixes — read before you --force:
npm audit fix # safe: upgrades within stated ranges
npm audit fix --dry-run --force # ALWAYS dry-run first
npm audit fix --force # only after reviewing the dry-run
npm audit fix --force can resolve an advisory by DOWNGRADING a package to an older version that doesn't trigger the audit signature. This is almost always wrong (e.g. downgrading next@16 to next@9 to "fix" a transitive postcss CVE). Inspect dry-run output for "Will install X@Y, which is a breaking change" — that's the tool trying to downgrade.
When npm audit fix cannot resolve an advisory (transitive dep pinned by an upstream package):
- Determine reachability — is the vulnerable code path actually invoked in your usage?
npm ls <package> + reading the parent's source can rule it out as unreachable.
- Consider a
package.json overrides pin to a patched version (test thoroughly — overrides can break the parent).
- Consider swapping the parent provider entirely.
- If none apply: document explicitly, track upstream, and note in the audit report rather than silently dropping the finding.
Step 3: Research Framework-Specific Known Issues
Beyond CVEs in packages, check for known vulnerability patterns specific to the framework in use. Search for recent advisories and common misconfiguration issues.
For every direct dependency, cross-reference the installed version against:
https://github.com/advisories?ecosystem=npm&query=<package>
https://github.com/<org>/<repo>/security/advisories
The framework-specific patterns below cover evergreen anti-patterns (mass assignment, debug-in-prod, etc.). Recent CVEs need a fresh check because hardcoded advisory lists rot fast and LLM training data is often 6+ months behind the latest.
Next.js / React:
- Server Actions exposing internal endpoints (pre-14.1.1 middleware bypass CVE-2025-29927)
dangerouslySetInnerHTML without sanitization
- SSRF through image optimization (
next/image with unrestricted domains)
- Exposed
.env files in public directory or client bundle (NEXT_PUBLIC_ prefix leaking secrets)
- Middleware auth bypass patterns — check middleware.ts matches all protected routes
- Server Component / Client Component boundary leaking server-only data:
- Any module reading
process.env.SECRET or instantiating a DB client should start with import "server-only"; — fails the build if imported from a Client Component
- Grep for: files in
lib/ that touch process.env.[A-Z_]+ but do NOT import server-only
- Inverse check: any file with
"use client" importing from such a module is a leak
- Outdated
next.config.js security headers
Django:
- DEBUG=True in production
- ALLOWED_HOSTS misconfigured (wildcard
*)
- Missing CSRF middleware or
@csrf_exempt on state-changing views
- Raw SQL via
extra(), raw(), or RawSQL without parameterization
- Pickle deserialization in sessions (use JSON serializer)
- Secret key committed to source control
Rails:
- Mass assignment without strong parameters
- SQL injection via
where("column = '#{input}'")
- Unpatched Action Pack, Action View, or Active Record CVEs
- Insecure deserialization in cookies (verify secret_key_base rotation)
- CSRF token bypass in API-only mode
Express / Node.js:
- Prototype pollution through
Object.assign, lodash.merge, deep-extend
- ReDoS (Regular Expression Denial of Service) in validation patterns
- Path traversal through
req.params in file serving routes
- Missing rate limiting on auth endpoints
eval() or Function() with user input
- Event loop blocking with synchronous operations
Serverless / edge runtimes (Vercel, Lambda, Cloud Run, Workers):
- In-memory state ≠ rate limit. A module-scoped
Map or Set for rate limiting, sessions, or caches is per-instance. Cold starts reset state; load spreads across instances; attackers bypass trivially.
- Grep for:
const rateLimitMap = new Map, const cache = new Map in server-action / API-route files
- Fix: shared store — Vercel KV, Upstash Ratelimit, Redis, DynamoDB
- Unbounded in-memory collections leak memory under traffic. Cap size and evict (LRU or FIFO).
x-forwarded-for trust: only trustworthy when the edge overwrites it. Behind misconfigured proxy chains it's attacker-spoofable. A fallback to a single "unknown" bucket throttles all anonymous traffic together; random-fallback silently disables the limit.
Spring / Java:
- Spring4Shell and related RCE vulnerabilities
- Deserialization attacks (Java native serialization, Jackson polymorphic types)
- SpEL injection in Spring Expression Language
- Missing CSRF protection on state-changing endpoints
- Actuator endpoints exposed without authentication
Laravel / PHP:
- APP_DEBUG=true in production (leaks env vars in error pages)
- SQL injection via raw DB queries without bindings
- Mass assignment without
$fillable / $guarded
- File upload without type validation (PHP execution via uploaded .php)
- Insecure deserialization in queued jobs
WordPress:
- Outdated core, theme, or plugin versions (most common attack vector)
- File editor enabled in wp-admin (allows code injection if admin is compromised)
- XML-RPC enabled (brute force amplification, SSRF)
- Default admin username, weak passwords
- Unpatched plugin vulnerabilities (check WPScan database)
Step 4: Check for Supply Chain Risks
Beyond known CVEs, look for supply chain attack indicators:
Dependency confusion / substitution:
- Private package names that could be claimed on public registries
- Missing
.npmrc or pip.conf scoping to private registry
- No lockfile integrity verification
Typosquatting:
- Package names that are close misspellings of popular packages
- Recently published packages with very few downloads
- Packages that changed ownership recently
Malicious packages:
- Postinstall scripts that make network requests or execute code (
scripts.postinstall in package.json)
- Packages with obfuscated code
- Excessive permission requests relative to functionality
Maintenance risk:
- Unmaintained packages (no commits in 2+ years, archived repos)
- Single-maintainer packages for critical functionality
- Packages with known but unpatched vulnerabilities (maintainer unresponsive)
Lockfile integrity:
- Lockfile committed?
git ls-files | grep -E 'package-lock\.json|yarn\.lock|pnpm-lock\.yaml|Gemfile\.lock|poetry\.lock|composer\.lock|Cargo\.lock|go\.sum'
- CI installs from lockfile?
- Check
.github/workflows/*.yml, .gitlab-ci.yml, Jenkinsfile, vercel.json, netlify.toml, Dockerfile
npm install (bad) vs npm ci (good); yarn install (bad) vs yarn install --immutable (good); pip install -r (bad) vs pip install --require-hashes -r (good)
integrity hashes present in the lockfile? (modern npm/pnpm yes by default)
Step 5: Check Dev Tool and CI/CD Security
GitHub Actions:
pull_request_target trigger with checkout of PR code (code injection risk)
- Secrets accessible in forked PR workflows
- Unpinned action versions (
uses: actions/checkout@main vs @v4.1.0 or SHA pin)
- Script injection via
${{ github.event.issue.title }} in run: blocks
Docker:
- Running as root in container (missing
USER directive)
- Base image with known CVEs (check with
trivy or docker scout)
- Secrets baked into image layers (visible via
docker history)
latest tag instead of pinned version
Terraform / IaC:
- Hardcoded secrets in
.tf files
- Unpinned provider versions
- Missing state file encryption
- Over-permissive IAM in provider configuration
Output Format
# Dependency & Stack Security Audit
## Project: [name]
## Stack: [language, framework, key tools]
## Date: [date]
### Stack Inventory
| Component | Version | Latest | Status |
|-----------|---------|--------|--------|
### Known Vulnerabilities (CVEs)
| Package | Installed | Vuln | Severity | Where reachable | CVE | Fix Version |
|---------|-----------|------|----------|-----------------|-----|-------------|
Where reachable values: `runtime` / `build-only` / `dev-only`. Confirm with `npm ls --omit=dev <package>` or inspect the deployment artifact (Vercel function bundle, Docker layer). Build- and dev-only vulnerabilities should not block a release on their own; runtime-reachable ones should.
### Framework-Specific Issues
#### [SEVERITY] [Title]
**Component:** [framework/tool name and version]
**Issue:** [description]
**Evidence:** [code or config snippet]
**Remediation:** [specific fix]
### Supply Chain Risks
| Risk | Package/Component | Details | Remediation |
|------|-------------------|---------|-------------|
### Dev Tool / CI Security
| Tool | Issue | Severity | Remediation |
|------|-------|----------|-------------|
### Prioritized Action Plan
1. [Critical — actively exploited CVEs, RCE vulnerabilities]
2. [High — known CVEs with public exploits, supply chain risks]
3. [Medium — framework misconfigurations, outdated dependencies]
4. [Low — maintenance risks, best practice improvements]
Boundaries
- Only audit code and configurations the user provides
- When identifying CVEs, verify they apply to the actual installed version
- Provide specific fix versions or remediation steps for every finding
- Note when a vulnerability requires specific conditions to exploit (reducing effective severity)
- Refuse to help exploit found vulnerabilities against unauthorized targets
References
- OWASP Dependency-Check
- National Vulnerability Database (NVD)
- GitHub Advisory Database
- Snyk Vulnerability Database
- npm audit / pip-audit / bundler-audit documentation
- SLSA (Supply-chain Levels for Software Artifacts) framework
1---
2name: dependency-audit
3description: "Audit project dependencies, frameworks, languages, and dev tools for known vulnerabilities, CVEs, and security anti-patterns. Use when the user mentions 'dependency audit,' 'npm audit,' 'CVE,' 'vulnerable packages,' 'supply chain security,' 'outdated dependencies,' 'known vulnerabilities,' 'security advisory,' 'package security,' 'framework vulnerability,' 'is this package safe,' or needs to check whether their stack has known security issues."
4allowed-tools: Bash, Read, Write, Grep, Glob, WebSearch
5---
6
7# Dependency Audit — Framework, Package, and Toolchain Security
8
9Audit project dependencies, frameworks, language runtimes, and dev tools for known vulnerabilities (CVEs), security anti-patterns, and supply chain risks.
10
11## Methodology
12
13### Step 1: Inventory the Stack
14
15Identify everything in use — not just direct dependencies but the full chain:
16
17**Package manifests — read and catalog:**
18```
19Node/JS: package.json, package-lock.json, yarn.lock, pnpm-lock.yaml
20Python: requirements.txt, Pipfile.lock, pyproject.toml, poetry.lock
21Ruby: Gemfile, Gemfile.lock
22Go: go.mod, go.sum
23Rust: Cargo.toml, Cargo.lock
24Java: pom.xml, build.gradle
25PHP: composer.json, composer.lock
26.NET: *.csproj, packages.config
27```
28
29**Framework and runtime versions:**
30- Check framework version (Next.js, Django, Rails, Spring, Laravel, Express, etc.)
31- Check language/runtime version (Node.js, Python, Ruby, Go, Java, PHP, .NET)
32- Check infrastructure tools (Docker base images, Terraform providers, Kubernetes versions)
33
34**Dev tools and CI/CD:**
35- Check CI/CD pipeline configs (.github/workflows, .gitlab-ci.yml, Jenkinsfile)
36- Check pre-commit hooks, linters, formatters
37- Check container base images and their update status
38- Check IaC tool versions (Terraform, Pulumi, CDK)
39
40**Edge cases in package manifests:**
41- `optionalDependencies` — installed but not audited by default
42- `peerDependencies` — version range may not match what's installed
43- `overrides` / yarn `resolutions` / pnpm `overrides` — check if used to *silence* advisories rather than fix them
44- Monorepos: read every `packages/*/package.json` and `apps/*/package.json`, not just the root
45- `engines` field — older-than-LTS Node makes other audits moot
46
47### Step 2: Run Automated Audit Tools
48
49Run the appropriate audit command for the project:
50
51```bash
52# Node.js
53npm audit --json # full structured output
54npm audit --omit=dev --json # production-only: filters dev/build-time vulns
55# Compare the two — vulns only in dev/build tooling do not ship to users
56# and should be triaged as lower priority. Don't bury this in the report.
57
58# Python
59pip audit # If pip-audit installed
60safety check # If safety installed
61
62# Ruby
63bundle audit
64
65# Go
66govulncheck ./...
67
68# Rust
69cargo audit
70
71# PHP
72composer audit
73
74# .NET
75dotnet list package --vulnerable
76
77# Docker
78docker scout cves <image>
79trivy image <image>
80
81# General (if Trivy is available)
82trivy fs .
83```
84
85**Applying fixes — read before you `--force`:**
86
87```bash
88npm audit fix # safe: upgrades within stated ranges
89npm audit fix --dry-run --force # ALWAYS dry-run first
90npm audit fix --force # only after reviewing the dry-run
91```
92
93`npm audit fix --force` can resolve an advisory by DOWNGRADING a package to an older version that doesn't trigger the audit signature. This is almost always wrong (e.g. downgrading `next@16` to `next@9` to "fix" a transitive postcss CVE). Inspect dry-run output for "Will install X@Y, which is a breaking change" — that's the tool trying to downgrade.
94
95**When `npm audit fix` cannot resolve an advisory** (transitive dep pinned by an upstream package):
96
971. **Determine reachability** — is the vulnerable code path actually invoked in your usage? `npm ls <package>` + reading the parent's source can rule it out as unreachable.
982. **Consider a `package.json` `overrides` pin** to a patched version (test thoroughly — overrides can break the parent).
993. **Consider swapping the parent provider entirely.**
1004. **If none apply:** document explicitly, track upstream, and note in the audit report rather than silently dropping the finding.
101
102### Step 3: Research Framework-Specific Known Issues
103
104Beyond CVEs in packages, check for known vulnerability patterns specific to the framework in use. Search for recent advisories and common misconfiguration issues.
105
106For every direct dependency, cross-reference the installed version against:
107- `https://github.com/advisories?ecosystem=npm&query=<package>`
108- `https://github.com/<org>/<repo>/security/advisories`
109
110The framework-specific patterns below cover *evergreen* anti-patterns (mass assignment, debug-in-prod, etc.). Recent CVEs need a fresh check because hardcoded advisory lists rot fast and LLM training data is often 6+ months behind the latest.
111
112**Next.js / React:**
113- Server Actions exposing internal endpoints (pre-14.1.1 middleware bypass CVE-2025-29927)
114- `dangerouslySetInnerHTML` without sanitization
115- SSRF through image optimization (`next/image` with unrestricted domains)
116- Exposed `.env` files in public directory or client bundle (`NEXT_PUBLIC_` prefix leaking secrets)
117- Middleware auth bypass patterns — check middleware.ts matches all protected routes
118- Server Component / Client Component boundary leaking server-only data:
119 - Any module reading `process.env.SECRET` or instantiating a DB client should start with `import "server-only";` — fails the build if imported from a Client Component
120 - Grep for: files in `lib/` that touch `process.env.[A-Z_]+` but do NOT import `server-only`
121 - Inverse check: any file with `"use client"` importing from such a module is a leak
122- Outdated `next.config.js` security headers
123
124**Django:**
125- DEBUG=True in production
126- ALLOWED_HOSTS misconfigured (wildcard `*`)
127- Missing CSRF middleware or `@csrf_exempt` on state-changing views
128- Raw SQL via `extra()`, `raw()`, or `RawSQL` without parameterization
129- Pickle deserialization in sessions (use JSON serializer)
130- Secret key committed to source control
131
132**Rails:**
133- Mass assignment without strong parameters
134- SQL injection via `where("column = '#{input}'")`
135- Unpatched Action Pack, Action View, or Active Record CVEs
136- Insecure deserialization in cookies (verify secret_key_base rotation)
137- CSRF token bypass in API-only mode
138
139**Express / Node.js:**
140- Prototype pollution through `Object.assign`, `lodash.merge`, `deep-extend`
141- ReDoS (Regular Expression Denial of Service) in validation patterns
142- Path traversal through `req.params` in file serving routes
143- Missing rate limiting on auth endpoints
144- `eval()` or `Function()` with user input
145- Event loop blocking with synchronous operations
146
147**Serverless / edge runtimes (Vercel, Lambda, Cloud Run, Workers):**
148- **In-memory state ≠ rate limit.** A module-scoped `Map` or `Set` for rate limiting, sessions, or caches is per-instance. Cold starts reset state; load spreads across instances; attackers bypass trivially.
149 - Grep for: `const rateLimitMap = new Map`, `const cache = new Map` in server-action / API-route files
150 - Fix: shared store — Vercel KV, Upstash Ratelimit, Redis, DynamoDB
151- **Unbounded in-memory collections** leak memory under traffic. Cap size and evict (LRU or FIFO).
152- **`x-forwarded-for` trust:** only trustworthy when the edge overwrites it. Behind misconfigured proxy chains it's attacker-spoofable. A fallback to a single `"unknown"` bucket throttles all anonymous traffic together; random-fallback silently disables the limit.
153
154**Spring / Java:**
155- Spring4Shell and related RCE vulnerabilities
156- Deserialization attacks (Java native serialization, Jackson polymorphic types)
157- SpEL injection in Spring Expression Language
158- Missing CSRF protection on state-changing endpoints
159- Actuator endpoints exposed without authentication
160
161**Laravel / PHP:**
162- APP_DEBUG=true in production (leaks env vars in error pages)
163- SQL injection via raw DB queries without bindings
164- Mass assignment without `$fillable` / `$guarded`
165- File upload without type validation (PHP execution via uploaded .php)
166- Insecure deserialization in queued jobs
167
168**WordPress:**
169- Outdated core, theme, or plugin versions (most common attack vector)
170- File editor enabled in wp-admin (allows code injection if admin is compromised)
171- XML-RPC enabled (brute force amplification, SSRF)
172- Default admin username, weak passwords
173- Unpatched plugin vulnerabilities (check WPScan database)
174
175### Step 4: Check for Supply Chain Risks
176
177Beyond known CVEs, look for supply chain attack indicators:
178
179**Dependency confusion / substitution:**
180- Private package names that could be claimed on public registries
181- Missing `.npmrc` or `pip.conf` scoping to private registry
182- No lockfile integrity verification
183
184**Typosquatting:**
185- Package names that are close misspellings of popular packages
186- Recently published packages with very few downloads
187- Packages that changed ownership recently
188
189**Malicious packages:**
190- Postinstall scripts that make network requests or execute code (`scripts.postinstall` in package.json)
191- Packages with obfuscated code
192- Excessive permission requests relative to functionality
193
194**Maintenance risk:**
195- Unmaintained packages (no commits in 2+ years, archived repos)
196- Single-maintainer packages for critical functionality
197- Packages with known but unpatched vulnerabilities (maintainer unresponsive)
198
199**Lockfile integrity:**
200- Lockfile committed? `git ls-files | grep -E 'package-lock\.json|yarn\.lock|pnpm-lock\.yaml|Gemfile\.lock|poetry\.lock|composer\.lock|Cargo\.lock|go\.sum'`
201- CI installs from lockfile?
202 - Check `.github/workflows/*.yml`, `.gitlab-ci.yml`, `Jenkinsfile`, `vercel.json`, `netlify.toml`, `Dockerfile`
203 - `npm install` (bad) vs `npm ci` (good); `yarn install` (bad) vs `yarn install --immutable` (good); `pip install -r` (bad) vs `pip install --require-hashes -r` (good)
204- `integrity` hashes present in the lockfile? (modern npm/pnpm yes by default)
205
206### Step 5: Check Dev Tool and CI/CD Security
207
208**GitHub Actions:**
209- `pull_request_target` trigger with checkout of PR code (code injection risk)
210- Secrets accessible in forked PR workflows
211- Unpinned action versions (`uses: actions/checkout@main` vs `@v4.1.0` or SHA pin)
212- Script injection via `${{ github.event.issue.title }}` in `run:` blocks
213
214**Docker:**
215- Running as root in container (missing `USER` directive)
216- Base image with known CVEs (check with `trivy` or `docker scout`)
217- Secrets baked into image layers (visible via `docker history`)
218- `latest` tag instead of pinned version
219
220**Terraform / IaC:**
221- Hardcoded secrets in `.tf` files
222- Unpinned provider versions
223- Missing state file encryption
224- Over-permissive IAM in provider configuration
225
226## Output Format
227
228```markdown
229# Dependency & Stack Security Audit
230## Project: [name]
231## Stack: [language, framework, key tools]
232## Date: [date]
233
234### Stack Inventory
235| Component | Version | Latest | Status |
236|-----------|---------|--------|--------|
237
238### Known Vulnerabilities (CVEs)
239| Package | Installed | Vuln | Severity | Where reachable | CVE | Fix Version |
240|---------|-----------|------|----------|-----------------|-----|-------------|
241
242Where reachable values: `runtime` / `build-only` / `dev-only`. Confirm with `npm ls --omit=dev <package>` or inspect the deployment artifact (Vercel function bundle, Docker layer). Build- and dev-only vulnerabilities should not block a release on their own; runtime-reachable ones should.
243
244### Framework-Specific Issues
245#### [SEVERITY] [Title]
246**Component:** [framework/tool name and version]
247**Issue:** [description]
248**Evidence:** [code or config snippet]
249**Remediation:** [specific fix]
250
251### Supply Chain Risks
252| Risk | Package/Component | Details | Remediation |
253|------|-------------------|---------|-------------|
254
255### Dev Tool / CI Security
256| Tool | Issue | Severity | Remediation |
257|------|-------|----------|-------------|
258
259### Prioritized Action Plan
2601. [Critical — actively exploited CVEs, RCE vulnerabilities]
2612. [High — known CVEs with public exploits, supply chain risks]
2623. [Medium — framework misconfigurations, outdated dependencies]
2634. [Low — maintenance risks, best practice improvements]
264```
265
266## Boundaries
267
268- Only audit code and configurations the user provides
269- When identifying CVEs, verify they apply to the actual installed version
270- Provide specific fix versions or remediation steps for every finding
271- Note when a vulnerability requires specific conditions to exploit (reducing effective severity)
272- Refuse to help exploit found vulnerabilities against unauthorized targets
273
274## References
275
276- OWASP Dependency-Check
277- National Vulnerability Database (NVD)
278- GitHub Advisory Database
279- Snyk Vulnerability Database
280- npm audit / pip-audit / bundler-audit documentation
281- SLSA (Supply-chain Levels for Software Artifacts) framework