Severity
P0 security / multi-tenant isolation.
Problem
GET /scans/{scan_id} authenticates an organization but currently loads DriftScan by scan_id alone. A leaked scan UUID can therefore bypass tenant ownership checks even though UUID guessing is impractical. Object identifiers are not authorization boundaries.
Required invariant
A scan is readable only when its workspace belongs to the authenticated organization.
Equivalent authorization condition:
scan.workspace.org_id == authenticated_org.id
The database query should enforce ownership directly (join/subquery), not fetch globally and check after serialization.
Required tests
- org A can read a scan belonging to org A
- org B receives 404 (preferred to avoid existence disclosure) for org A's scan ID
- unauthenticated request remains 401
- findings returned through the scan cannot cross organization boundaries
Release gate
PR #1 remains draft and the evidence-core redesign must not be presented as multi-tenant production-ready until this is fixed and regression-tested.
Severity
P0 security / multi-tenant isolation.
Problem
GET /scans/{scan_id}authenticates an organization but currently loadsDriftScanbyscan_idalone. A leaked scan UUID can therefore bypass tenant ownership checks even though UUID guessing is impractical. Object identifiers are not authorization boundaries.Required invariant
A scan is readable only when its workspace belongs to the authenticated organization.
Equivalent authorization condition:
The database query should enforce ownership directly (join/subquery), not fetch globally and check after serialization.
Required tests
Release gate
PR #1 remains draft and the evidence-core redesign must not be presented as multi-tenant production-ready until this is fixed and regression-tested.