Skip to content

[Bug] Org Scan Result Endpoints Missing Authentication — Data Exfiltration Path #322

Description

@ionfwsrijan

Description

Org scan creation requires an API key, but all result-access endpoints (findings, summary, PDF report, blast radius, abort, SSE stream) lack authentication. The security model says "you must authenticate to start a scan" but then "anyone can read all results." If the org_job_id UUID is leaked through any vector, an unauthenticated attacker can access the complete vulnerability posture of the entire organization.

Actual Behavior

backend/app/main.py:

POST /api/scans/org              → HAS auth (line 1655)
GET  /api/scans/org/{id}/status  → HAS auth (line 1691)
POST /api/scans/org/{id}/abort   → NO auth (line 1724)
GET  /api/scans/org/{id}/stream  → NO auth (line 1761)
GET  /api/scans/org/{id}/summary → NO auth (line 1808)
GET  /api/scans/org/{id}/findings → NO auth (line 1867)
GET  /api/scans/org/{id}/report/pdf → NO auth (line 1904)
GET  /api/scans/org/{id}/blast-radius → NO auth (line 2012)

The org_job_id is a UUID (uuid.uuid4() at main.py line 1671), which is not guessable. However, it leaks through:

  • SSE stream URL (visible in browser network tab)
  • Referrer headers
  • Shared links between team members
  • Frontend localStorage (patchpilot:lastScan)

Impact

An unauthenticated attacker who obtains the UUID can:

  • Access ALL findings for EVERY repository in the organization
  • Download the full PDF audit report
  • View the dependency blast radius graph
  • Abort running scans (denial of service)
  • Access real-time scan progress via SSE stream

Expected Behavior

All org scan result endpoints must require the same authentication as the creation endpoint.

Proposed Fix

  1. main.py: Add Depends(verify_api_key) to all org scan result endpoints (abort, stream, summary, findings, report/pdf, blast-radius)
  2. Alternatively, implement a scoped token issued at scan creation time that grants read access to that specific scan's results
  3. api.ts: Update the frontend to send auth headers with these requests (once Issue Persist findings to SQLite on every scan completion #2 is resolved)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions