diff --git a/docs/dependency-audit.md b/docs/dependency-audit.md new file mode 100644 index 0000000..15025fe --- /dev/null +++ b/docs/dependency-audit.md @@ -0,0 +1,75 @@ +# Dependency Audit — INS-010 | CC-047 | 2026-07-31 + +## Executive Summary + +**Project**: ceo-api (NestJS 11, Node 22) +**Tool**: `npm audit` +**Total dependencies**: ~450 (direct + transitive) + +| Severity | Count | Runtime | Dev-only | +|----------|-------|---------|----------| +| Critical | 0 | 0 | 0 | +| High | 25 | 1 | 24 | +| Moderate | 5 | 0 | 5 | + +--- + +## Critical Production Finding + +### [HIGH — RUNTIME] drizzle-orm SQL Injection +- **Advisory**: GHSA-gpj5-g38j-94v9 +- **Affected range**: `<0.45.2` (current: `0.36.4`) +- **Fix**: Upgrade to `>=0.45.2` +- **Status**: FACT — confirmed by `npm audit` +- **Risk assessment**: MEDIUM-LOW for this project + - We use only the ORM builder API (no raw SQL with user-supplied identifiers) + - All identifiers (table/column names) come from the Drizzle schema constants + - The vulnerability affects `sql\`SELECT * FROM \${userInput}\`` patterns — not used +- **Remediation**: Planned upgrade in CC-048/CC-049 cycle; requires testing for 0.36→0.45 breaking changes (drizzle-kit, schema API changes) +- **Owner**: Engineering + +--- + +## Dev-Only Findings (24 HIGH, 5 MODERATE — no production risk) + +All remaining vulnerabilities are in devDependencies not included in the production Docker image: + +| Package | Severity | Via | Production? | +|---------|----------|-----|-------------| +| jest / jest-circus / ts-jest | HIGH | @jest/transform → babel-plugin-istanbul | No | +| @nestjs/cli | HIGH | fork-ts-checker-webpack-plugin → minimatch | No | +| drizzle-kit | MODERATE | @esbuild-kit/esm-loader | No | +| js-yaml | HIGH | prototype pollution in merge | No (swagger dev only) | +| lodash | HIGH | Code injection via `_.template` | No | +| brace-expansion / minimatch | HIGH | DoS via unbounded expansion | No | +| esbuild | MODERATE | dev server SSRF | No | + +**Verification**: Production Docker image uses `--omit=dev` → none of these packages are shipped. + +--- + +## Outdated Major Versions (upgrade planned) + +| Package | Current | Latest | Risk | +|---------|---------|--------|------| +| drizzle-orm | 0.36.4 | 0.45.2 | HIGH — breaking API changes | +| drizzle-kit | 0.28.1 | 0.31.10 | MEDIUM — migration tool | +| @nestjs/swagger | 8.1.1 | 11.4.6 | HIGH — major version | +| bullmq | 5.80.9 | 6.0.2 | MEDIUM — possible API changes | +| @casl/ability | 6.8.1 | 7.0.1 | LOW — check for breaking changes | +| @nestjs/schedule | 5.0.1 | 6.1.3 | LOW — just upgraded | + +**Recommendation**: Schedule a dedicated dependency upgrade sprint (CC-049 or separate task) rather than upgrading mid-feature cycle. Pin major versions until tested. + +--- + +## Residual Risk + +| Risk | Likelihood | Impact | Accepted by | +|------|-----------|--------|-------------| +| drizzle-orm SQLi in ORM API usage | LOW (pattern not used) | HIGH (data breach) | Engineering — schedule upgrade | +| Jest vuln exploited in CI | VERY LOW (dev env only) | MEDIUM | Engineering — accepted | + +--- + +*Next review: before CC-049 (Livrare) or when any package reaches end-of-life.*