Scan run start: 2026-04-25T05:29:29Z (UTC)
Scan run end: 2026-04-25T05:37:27Z (UTC)
Scan duration: ~8m
Scanner host: macOS / darwin 25.4.0 (operator workstation)
Tools run: gitleaks v8.30.1, bandit v1.9.4, pip-audit v2.10.0, npm v10.7.0 (audit), trivy v0.70.0
Branch scanned: security/scan-baseline-2026-04-25 (HEAD of main at 77a3403 + nothing else local)
Operator-facing executive summary: 0 CRITICAL, 5 HIGH, 6 MEDIUM, ~67 LOW. No live secret in repo or git history. Console (Raptor-adjacent operator console) ships an outdated cryptography/pyopenssl/flask set with multiple HIGH CVEs — must rotate before any console GA. Frontend lockfile pins a known-RCE serialize-javascript@6.0.2. No CRITICAL findings; no Slack page sent.
| Severity | Count | Issue routing |
|---|---|---|
| CRITICAL | 0 | n/a |
| HIGH | 5 | filed as #288, #289, #290, #291, #292 |
| MEDIUM | 6 | batched (table below) |
| LOW | ~67 | batched (counts only) |
| INFO | 4 | documented; no issue |
First-run baseline notes:
- This is the first structured nightly-scan output. Subsequent scans diff against this file.
- Scanner installs were performed on this run: brew install gitleaks trivy + pip3 install --break-system-packages --user bandit pip-audit. Nightly automation should pre-install these in CI; today they are operator-local.
- Bandit was run twice — once unfiltered (31,494 findings, almost all in vendored .venv/ / node_modules/) and once with -x "*/.venv/*,*/node_modules/*,*/tests/*,*/.clone/*,*/.claude/*" for actionable signal (60 findings, 0 HIGH, 2 MEDIUM, 58 LOW). The filtered report (reports/bandit-app.json) is the source of truth for triage; the unfiltered report (reports/bandit.json) is retained for completeness only.
- Trivy was run with --severity HIGH,CRITICAL per the agent spec. .claude/worktrees/ and .clone/ produced 14 noise-vulns from old pinned dependency files in ephemeral agent worktrees; those are excluded from the HIGH count below. Recommendation: add .claude/worktrees/ and .clone/ to a trivy --skip-dirs list in nightly automation.
- npm audit was invoked with --omit=dev. react-scripts is currently listed under dependencies (not devDependencies) in frontend/trademaster_ui/package.json, which is why its build-time transitive deps still appear. Most of those vulns are not exploitable in the production bundle (they ship in dev-server, jest, workbox-build at compile time), but serialize-javascript is bundled by the production build and IS reachable.
- Cite-source convention: every finding below cites the file:line, the CVE/GHSA ID, and a vendor-advisory URL.
None. No live secrets in repo or git history. No SQL injection / RCE in app code. No unauthenticated admin endpoint discovered by these scanners. (The C1–C4 findings from the 2026-04-24 review are not visible to these scanners — they are runtime / configuration findings — and remain tracked in the prior security review document.)
cryptography==42.0.8 in console: 4 known HIGH CVEs (filed #288)Tool: pip-audit (reports/pip-audit-console.json) + trivy (reports/trivy.json)
Confidence: HIGH (multiple independent scanners; CVE IDs match GHSA records)
Finding. console/requirements.txt pins cryptography==42.0.8. Four advisories apply:
- CVE-2026-26007 (HIGH) — fix: >=46.0.5. Public-key parsing flaw affecting EllipticCurvePublicNumbers.public_key(), load_der_public_key(), load_pem_public_key().
- CVE-2026-34073 (HIGH) — fix: >=46.0.6. DNS name-constraint bypass — name constraints validated only against SAN, not peer name.
- CVE-2024-12797 (HIGH) — fix: >=44.0.1. OpenSSL static-link issue.
- GHSA-h4gh-qq45-vh27 (advisory) — fix: >=43.0.1. OpenSSL static-link issue.
Evidence.
- console/requirements.txt line pinning cryptography==42.0.8
- pip-audit JSON: reports/pip-audit-console.json (4 entries under cryptography)
- trivy JSON: reports/trivy.json flags CVE-2026-26007 against console/requirements.txt
Risk. The console application uses webauthn / passkey crypto (it pins webauthn package). A bug in EC public-key parsing or DNS name-constraint validation would weaken authentication. Blast radius: any future operator console exposed to user-controlled certs / public keys. Currently low real-world exposure because the console is not live.
Remediation. Bump cryptography to >=46.0.6 in console/requirements.txt, run console test suite, redeploy. Pin >=46.0.6,<47 to prevent silent major upgrades. Routing: feature-developer.
Routing: Triage owner: sre-agent — see #145 + the agent spec for routing rules. Code fix: feature-developer (console).
pyopenssl==25.1.0 in console: 2 known HIGH CVEs (filed #289)Tool: pip-audit (reports/pip-audit-console.json)
Confidence: HIGH (vendor advisory matches version)
Finding. console/requirements.txt pins pyopenssl==25.1.0. Two advisories apply:
- CVE-2026-27448 (HIGH) — fix: >=26.0.0. Unhandled exception in set_tlsext_servername_callback results in connection being accepted — auth bypass when callback is used as a security gate.
- CVE-2026-27459 (HIGH) — fix: >=26.0.0. Buffer overflow in set_cookie_generate_callback if returned cookie >256 bytes.
Evidence.
- console/requirements.txt line pinning pyopenssl==25.1.0
- pip-audit JSON: reports/pip-audit-console.json (2 entries under pyopenssl)
Risk. Auth-bypass-class CVE. If the console ever uses TLS SNI callbacks for tenant routing or auth gating, an attacker-triggered exception in the callback fails open (connection accepted). Buffer overflow is contingent on a callback we control returning >256 bytes — lower likelihood but high blast radius if hit. Currently low real-world exposure (console not live).
Remediation. Bump pyopenssl to >=26.0.0 in console/requirements.txt. Confirm no breaking API changes in the SNI callback path. Pin >=26.0.0,<27.
Routing: Triage owner: sre-agent — see #145 + the agent spec for routing rules. Code fix: feature-developer (console).
flask==3.0.3 in console: CVE-2026-27205 (cache poisoning via missing Vary header) (filed #290)Tool: pip-audit (reports/pip-audit-console.json)
Confidence: HIGH
Finding. console/requirements.txt pins flask==3.0.3. CVE-2026-27205 — when session is accessed, Flask should set Vary: Cookie so caches do not cross-contaminate logged-in users; pre-3.1.3 it does not. Fix: >=3.1.3.
Evidence.
- console/requirements.txt pin on flask==3.0.3
- pip-audit JSON: reports/pip-audit-console.json
- Backend (backend_v2/requirements.txt) is on Flask 3.1.3 already — pip-audit shows zero vulns. So this is a console-only drift.
Risk. Cache-poisoning / session leakage at any reverse proxy (Cloudflare, Heroku router, browser cache) that respects Vary. User A's session response could be served to User B. Console is not yet live, but is in active development with passkey login — this would be exploitable on day one of console GA.
Remediation. Bump flask to >=3.1.3,<4 in console/requirements.txt. Re-run console session tests.
Routing: Triage owner: sre-agent — see #145 + the agent spec for routing rules. Code fix: feature-developer (console).
serialize-javascript@6.0.2 in frontend lockfile: GHSA-5c6j-r48x-rmvq (RCE, CVSS 8.1) (filed #291)Tool: npm audit (reports/npm-audit.json) + trivy (reports/trivy.json)
Confidence: HIGH (independent confirmation)
Finding. frontend/trademaster_ui/package-lock.json pins serialize-javascript@6.0.2 (transitive via react-scripts@5.0.1 → workbox-webpack-plugin / css-minimizer-webpack-plugin / terser). GHSA-5c6j-r48x-rmvq (CVSS 8.1, HIGH): RCE via crafted RegExp.flags and Date.prototype.toISOString() payloads. Also GHSA-1115723 (CVSS 5.9): CPU-exhaustion DoS via array-like objects. Fix: >=7.0.3.
Evidence.
- frontend/trademaster_ui/package-lock.json
- npm audit advisory IDs 1113686 and 1115723
- trivy: reports/trivy.json
Risk. serialize-javascript is used by the production build pipeline (workbox service-worker generation, terser minification). The RCE vector is operative if attacker-controlled data flows through serialize() — at build time, that means a malicious dep or a build-server compromise. Lower likelihood but the package is also used by webpack-dev-server (dev-only, not prod). The advisory's main concern is the build pipeline; in our deploy, that's GitHub Actions running npm run build. Practical risk today: medium-low; advisory severity: HIGH; we follow advisory severity per the agent spec.
Remediation. Bump react-scripts to a version that pins serialize-javascript>=7.0.3 (options: stay on CRA 5.0.1 + use npm overrides to force-bump the transitive; or migrate off CRA entirely). Recommend an overrides block as the minimal fix:
"overrides": { "serialize-javascript": ">=7.0.3" }
Routing: Triage owner: sre-agent — see #145 + the agent spec for routing rules. Code fix: feature-developer (frontend / Antlers).
Tool: trivy (reports/trivy.json)
Confidence: MEDIUM (these are stale snapshots, not the live manifests)
Finding. Trivy flagged HIGH CVEs against:
- Flask-Cors==4.0.0 (CVE-2024-6221)
- Werkzeug==2.3.7 (CVE-2024-34069)
- gunicorn==21.2.0 (CVE-2024-1135 + CVE-2024-6827)
These pins are NOT in current backend_v2/requirements.txt (which pip-audit certifies as clean). They are inside .claude/worktrees/agent-ab4de9b8/backend_v2/requirements.txt — an ephemeral Claude-agent worktree captured before the previous dep-bump.
Evidence. reports/trivy.json — all 4 entries have Target prefixed with .claude/worktrees/agent-ab4de9b8/.
Risk. Effectively zero — the worktree is not deployed. However, these worktrees ARE indexed by trivy and skew nightly counts. Operationally this is HIGH-severity noise that will cause "phantom regressions" in the diff against this baseline.
Remediation. Add .claude/worktrees/ and .clone/ to nightly trivy --skip-dirs. File this as a tooling ticket against operator (not feature-developer).
Routing: Triage owner: sre-agent — see #145 + the agent spec for routing rules. Tooling fix: operator.
| ID | Tool | Finding | File / package | Owner | Notes |
|---|---|---|---|---|---|
| M-1 | npm audit | webpack-dev-server <=5.2.0 ws/sockjs path-traversal (transitive via react-scripts) |
frontend lockfile | feature-developer | Fixed by react-scripts upgrade or override |
| M-2 | npm audit | sockjs >=0.3.17 uuid bounds-check missing |
frontend lockfile | feature-developer | Same upstream fix path as M-1 |
| M-3 | npm audit | uuid <14.0.0 buffer-bounds in v3/v5/v6 (CVSS 0 but flagged) |
frontend lockfile | feature-developer | Low real exposure; bundle with M-1/M-2 fix |
| M-4 | npm audit | @pmmmwh/react-refresh-webpack-plugin moderate (transitive) |
frontend lockfile | feature-developer | Build-time only |
| M-5 | bandit B104 | app.run(host='0.0.0.0') in backend_v2/app.py:27 |
backend_v2 | sre-agent | Intentional for Heroku container; suggest comment + nosec annotation |
| M-6 | bandit B104 | app.run(host='0.0.0.0') in console/wsgi.py:8 |
console | sre-agent | Same as M-5 |
.venv/node_modules/tests exclusion): 58random module — not used for crypto), B404 (subprocess module imported), B603/B607 (subprocess call w/o shell=True), B105 (hardcoded password-like strings — false positive on fixture / test data)gitleaks flagged docs/legal/nda-framework.md:325 as generic-api-key. Investigation: the matched string CommunityKey=2c04b76c-2b7d-4399-977e-d5876ba7e034 is a public URL anchor for the Uniform Law Commission's UETA committee page (https://www.uniformlaws.org/committees/community-home?CommunityKey=...). Not a secret. Recommendation: add a gitleaks allowlist entry for uniformlaws.org URLs. Confidence: HIGH this is a false-positive. No issue filed.DS-0002 Image user should not be 'root'; DS-0017 RUN <package-manager> update instruction alone) inside node_modules/@surma/rollup-plugin-off-main-thread/Dockerfile and node_modules/jsonpath/Dockerfile. These are example Dockerfiles inside third-party npm packages, not Raxx's container build. Not actionable. Recommendation: add node_modules/ to trivy --skip-dirs.backend_v2/.venv/ or console/.venv/ — vendored Python deps, not Raxx code. Filtered run produced 0 HIGH. Operationally: nightly automation MUST exclude .venv/, node_modules/, .claude/, .clone/ to produce useful signal.backend_v2/requirements.txt shows zero known vulns. Recent dep-hygiene work (#228 hotfix per the 2026-04-24 review) is paying off here.--omit=dev does not fully isolate production deps because react-scripts is mis-listed under dependencies), trivy ok (with --skip-dirs guidance).last_rotated_at retrieval is part of the runbook but not yet automated. Tooling gap; tracked as part of the runbook follow-up below.reports/ (gitignored — see commit).docs/security/scans/ directory.scripts/security/install-scanners.sh (or Brewfile + pip constraints file) so nightly CI can self-bootstrap.--skip-dirs. Without it, ephemeral worktrees produce phantom HIGH counts. Suggested: --skip-dirs ".claude/worktrees,.clone,node_modules,**/.venv".bandit -r backend_v2/ console/ -x "*/.venv/*,*/node_modules/*,*/tests/*,*/.clone/*,*/.claude/*".uniformlaws.org URL anchors (and likely future false-positives in legal/regulatory citations). Add .gitleaks.toml.react-scripts is listed under dependencies, not devDependencies. Either move it (semantically cleaner) or accept that --omit=dev will continue to include the build chain.last_rotated_at tracking. File operator ticket.The next nightly scan (2026-04-26) will diff against: - HIGH count: 5 (this run). New HIGHs above this baseline → escalate. - MEDIUM count: 6. - LOW count: ~67 (subject to noise; treat ±10% as stable). - Net-new packages with CVEs: 0 baseline; deltas reportable.
.claude/agents/security-agent.mddocs/security/2026-04-24-security-review.mddocs/security/release-readiness-policy.mdreports/gitleaks.jsonreports/bandit.json (unfiltered, retained for completeness)reports/bandit-app.json (filtered, source-of-truth for triage)reports/pip-audit-backend.jsonreports/pip-audit-console.jsonreports/npm-audit.jsonreports/trivy.json