All documentation

Reviews & Audits

Module 18 — Dependency Security Audit

Task #524 (Phase 22). This is a fresh, hands-on audit pass over this repository's actual dependency graph, distinct from docs/security/supply-chain.md (Module 15's policy document, which describes the scanning/update infrastructure — CodeQL, pnpm audit, cargo audit, Dependabot — rather than auditing today's actual dependency versions). This document is the audit; that document remains the policy reference.

What this audit could and could not do in this environment

pnpm audit and cargo audit (the tools security-scan.yml runs in CI) require shell/network access this sandbox does not grant this session — confirmed by a denied mcp__workspace__bash permission request. Per this module's standing discipline, that is disclosed here rather than silently skipped: no automated vulnerability-database lookup was run. What follows instead is a manual review of every package.json/Cargo.toml in the monorepo, read in full, checked against this reviewer's knowledge of the ecosystem for anything that stood out as outdated, abandoned, or carrying a widely-known historical CVE class — a real but strictly weaker check than an actual advisory-database query. security-scan.yml's scheduled Monday run remains the authoritative, up-to-date source of truth once this repository is pushed to GitHub with Actions enabled.

Findings

1. CORRECTED (post-Module-18 reconciliation): this finding was a false negative — the Python and Go SDKs do exist, at sdks/python and sdks/go

Original Phase 22 text, preserved for the record: "While tracing every ecosystem this monorepo should have a Dependabot entry for, packages/sdk-python and packages/sdk-go were checked and confirmed not to exist — not empty stubs, not present under a different path, simply absent. packages/sdk-typescript (@pentesthub/sdk) is the only SDK package that actually exists in the repository today." That conclusion was wrong, and the error was methodological: this audit checked exactly one path convention (packages/sdk-*, the pnpm-workspace pattern the TypeScript SDK uses) and, on finding nothing there, concluded the SDKs were absent — without searching for them under any other path.

A dedicated post-Module-18 reconciliation pass (docs/reviews/0021-post-m18-sdk-reconciliation.md) found both SDKs alive and well at sdks/python and sdks/go — outside packages/ entirely, which is in fact the correct convention here: pnpm-workspace.yaml only globs apps/* and packages/*, so a Python or Go package placed under packages/ would be silently swept into pnpm tooling that can't build it. sdks/ has held both SDKs since Modules 7-10 (git log --diff-filter=A -- sdks/python/pentesthub_ai/client.py resolves to commit 357d97f, "Modules 7-10: Desktop Agent, Browser Extension, Bug Bounty OS, Enterprise Platform"), and both were extended correctly in Module 16 (task #429) and Module 17 (task #491) — 14 resource classes each, verified field-for-field identical in scope to the TypeScript SDK's own 14. Every prior task that reported "Python SDK tests," "Go SDK build + test," or "SDK update (TypeScript/Python/Go)" as complete was reporting accurately; this Phase 22 audit was the one link in the chain that was wrong, not the underlying task history.

This also means .github/dependabot.yml having no pip/gomod ecosystem entries, described below as "correct, not a gap," was itself based on the same false premise — see the reconciliation doc for the corrected assessment of that specific point.

2. apps/api dependency review — no concerns

Read in full (apps/api/package.json). Every dependency is on a current major version consistent with a project actively maintained in 2026: NestJS 11, Prisma 7.8 (with @prisma/adapter-pg, the modern driver-adapter pattern rather than the deprecated binary-engine default), Express 5.2, Zod 4.4, argon2 0.44 for password hashing (a stronger, memory-hard choice over bcrypt), helmet 8, class-validator 0.15. No dependency is pinned to an end-of-life major (e.g., no Express 4, no NestJS 8/9, no jsonwebtoken used directly — token signing goes through @nestjs/jwt). otplib (TOTP for MFA) and qrcode are both current. Nothing here prompted a closer look beyond what pnpm audit would already catch automatically in CI.

3. apps/web dependency review — no concerns

Read in full (apps/web/package.json). Next.js 16.2.0, React 19.2.0 — both current majors. react-markdown (used to render AI chat responses and other user/AI-generated Markdown) is used without the rehype-raw plugin anywhere in the dependency tree — confirmed by grep, no such package is installed — meaning raw HTML embedded in Markdown input is never parsed as HTML by default, which is the safe default for a chat surface that renders content an AI model (and, transitively, whatever untrusted context that model was given) produced. This is worth recording explicitly: it is a correct-by-omission security property of the current dependency choice, and a future contributor adding rehype-raw to enable some Markdown feature would silently reopen an XSS surface in AI chat rendering — flagging this here so Phase 29's documentation captures it as a constraint, not just an audit non-finding.

4. apps/desktop/src-tauri (Rust) dependency review — no concerns

Read in full (Cargo.toml). Tauri 2, sqlx 0.8, reqwest 0.12, axum 0.7 for the Local Bridge Server — current, actively maintained crates. Cryptographic/secrets-adjacent crates (keyring, aes-gcm, sha2) are on recent major versions. Nothing here prompted a closer look beyond what cargo-audit (already wired into security-scan.yml) would catch automatically.

5. CORRECTED (post-Module-18 reconciliation): Dependabot coverage was NOT complete — pip/gomod entries for sdks/python/sdks/go were missing

Original Phase 22 text, preserved for the record: "Re-checked .github/dependabot.yml against the actual monorepo layout (not the aspirational one implied by task history): npm (root...), cargo (apps/desktop/src-tauri), pub (apps/mobile), docker (apps/api, apps/web), and github-actions. This is complete coverage of every ecosystem that has files in this repository today. No entry needs to be added or removed as a result of this audit." This inherited the same false premise as Finding #1 above (that sdks/python/sdks/go don't exist) and was therefore also wrong — pip/gomod entries for sdks/python/sdks/go were genuinely missing. Both were added during the post-Module-18 reconciliation checkpoint; see docs/reviews/0021-post-m18-sdk-reconciliation.md.

Verdict

No newly-introduced vulnerable dependency was found by this manual pass. The one real finding is #1 above — an integrity gap in the project's own history, not a supply-chain vulnerability — and it is carried forward to Phase 29 for consolidated disclosure rather than acted on unilaterally in this phase.