Skip to content

Security: pre-launch hardening (Critical/High findings)#3

Merged
swsOG merged 1 commit into
codex/unified-scan-intakefrom
security/launch-hardening
Jun 9, 2026
Merged

Security: pre-launch hardening (Critical/High findings)#3
swsOG merged 1 commit into
codex/unified-scan-intakefrom
security/launch-hardening

Conversation

@swsOG

@swsOG swsOG commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Implements the fixes from the pre-launch security assessment. All changes are server-side; no scan-station UI changes.

What's fixed

ScanStation API (server.py)

  • Loopback-only Host guard → blocks DNS-rebinding / off-host access.
  • Path-segment sanitisation on every route → blocks the path-traversal that read portal.db (password hashes) and .env (secret key). This breaks the "steal secret → forge admin session" chain.
  • Generic error messages (no internal path leakage).

Portal (portal_new/app.py)

  • Refuses to boot on a weak/placeholder PORTAL_SECRET_KEY.
  • Per-account login lockout + stops trusting X-Forwarded-For → brute force can no longer be bypassed by rotating IPs.
  • Security headers: CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, HSTS (HTTPS).
  • Fail-closed tenant scoping (denies when a non-admin's client can't resolve).
  • Generic error responses; debug-in-prod guard; wsgi.py for gunicorn.

Deps/CI

  • pypdf 6.10.2 + pytest 9.0.3 (CVE fixes). New GitHub Action runs pip-audit + pytest.

Verification

  • 76 tests pass (incl. new test_scanstation_security.py / test_portal_security.py).
  • Re-ran the live exploit suite against the patched build: the traversal → portal.db/.env theft, the admin-session forgery, and the brute-force bypass are all now blocked. IDOR / CSRF / chat-auth controls still hold. pip-audit: clean.

Notes

  • Base is codex/unified-scan-intake (the branch this builds on) for a clean diff — retarget to main if preferred.
  • By design (agreed scope), ScanStation still allows same-host local calls without a token; the remote vector is closed by the Host guard. Adding a session token (deferred) would also block local-process access.
  • PORTAL_SECRET_KEY rotation + TLS/HSTS termination are deployment-side.

🤖 Generated with Claude Code

ScanStation (server.py): loopback-only Host guard + path-segment sanitisation
(blocks the DNS-rebinding and path-traversal -> portal.db/.env theft chain); generic
error messages.

Portal (portal_new/app.py): refuse to boot on a weak/placeholder PORTAL_SECRET_KEY;
per-account login lockout + stop trusting X-Forwarded-For (brute-force defence);
security headers (CSP, X-Frame-Options, nosniff, Referrer-Policy, HSTS on HTTPS);
fail-closed tenant scoping; generic error responses; debug-in-prod guard.

Deps/CI: pypdf 6.10.2 + pytest 9.0.3 (CVE fixes), pip-audit + pytest GitHub Action,
wsgi.py for gunicorn. New tests: test_scanstation_security.py, test_portal_security.py.
All 76 tests pass; re-running the exploit suite confirms the Critical/High chain is closed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@swsOG swsOG merged commit ac17dee into codex/unified-scan-intake Jun 9, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant