You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
Fixed on feat/evidence-core-v1 in commit 4cb068d5ea952cf0689d56aad1e84a00acc84161.
Verification:
scan lookup now joins Workspace and requires Workspace.org_id == authenticated_org.id
finding serialization requires both the authorized scan_id and the scan's workspace_id
regression test proves owner access succeeds, another organization receives 404 for the same scan UUID, unauthenticated access receives 401, and deliberately inconsistent cross-workspace finding data is not serialized
Activity
EdwinJdevops commentedon Sep 14, 2026
Fixed on
feat/evidence-core-v1in commit4cb068d5ea952cf0689d56aad1e84a00acc84161.Verification:
Workspaceand requiresWorkspace.org_id == authenticated_org.idscan_idand the scan'sworkspace_idThe security invariant is now query-enforced; UUID secrecy is not used as authorization.