clawd/memory/shannon-scan-2026-02-14/deliverables/authz_exploitation_queue.json

144 lines
9.2 KiB
JSON

{
"vulnerabilities": [
{
"ID": "AUTHZ-VULN-01",
"vulnerability_type": "Horizontal",
"externally_exploitable": true,
"endpoint": "GET /dossier/{id}/export",
"vulnerable_code_location": "/repos/inou-portal/lib/stubs.go:197",
"role_context": "user with PermRead on any dossier",
"guard_evidence": "lib.DossierGet ignores AccessContext parameter - directly calls entryQuery without authorization",
"side_effect": "export complete dossier data including PII and medical records for other users",
"reason": "Stub function DossierGet accepts ctx parameter but never uses it, bypassing all authorization checks",
"minimal_witness": "1) Create two accounts A and B; 2) Login as A; 3) GET /dossier/{B_id}/export using B's dossier ID; 4) Receive B's complete health records",
"confidence": "high",
"notes": "Portal layer has weak pre-filter checking IsCareReceiver flag, but lib.DossierGet provides no defense-in-depth"
},
{
"ID": "AUTHZ-VULN-02",
"vulnerability_type": "Horizontal",
"externally_exploitable": true,
"endpoint": "GET /api/v1/dossiers/{id}",
"vulnerable_code_location": "/repos/inou-portal/lib/stubs.go:197",
"role_context": "user with valid API Bearer token",
"guard_evidence": "v1CanAccess check at API layer, but lib.DossierGet(nil, id) ignores authorization",
"side_effect": "read dossier metadata (name, email, DOB, sex) for other users",
"reason": "Single layer of defense - v1CanAccess is only check, lib function ignores context",
"minimal_witness": "1) Get valid Bearer token; 2) Call GET /api/v1/dossiers/{victim_id}; 3) Bypass depends on v1CanAccess having bugs",
"confidence": "med",
"notes": "Requires bypassing v1CanAccess check first, but no secondary defense exists"
},
{
"ID": "AUTHZ-VULN-03",
"vulnerability_type": "Horizontal",
"externally_exploitable": true,
"endpoint": "GET /api/v1/dossiers/{id}/entries",
"vulnerable_code_location": "/repos/inou-portal/lib/stubs.go:101",
"role_context": "user with valid API Bearer token",
"guard_evidence": "Uses lib.SystemAccessorID which bypasses CheckAccess (rbac.go:20)",
"side_effect": "list all medical entries for other users' dossiers",
"reason": "lib.EntryList called with SystemAccessorID - CheckAccess returns true for system accessor",
"minimal_witness": "1) Get valid Bearer token; 2) Call GET /api/v1/dossiers/{victim_id}/entries after bypassing v1CanAccess; 3) Receive all entries",
"confidence": "med",
"notes": "Requires bypassing v1CanAccess, then SystemAccessorID bypasses lib layer"
},
{
"ID": "AUTHZ-VULN-04",
"vulnerability_type": "Horizontal",
"externally_exploitable": true,
"endpoint": "GET /api/v1/dossiers/{id}/access",
"vulnerable_code_location": "/repos/inou-portal/lib/stubs.go:295-299",
"role_context": "user with valid API Bearer token",
"guard_evidence": "lib.AccessList has no AccessContext parameter - directly queries access table",
"side_effect": "view access control lists showing who has access to a dossier",
"reason": "AccessList function fundamentally cannot enforce authorization - no context parameter",
"minimal_witness": "1) Get valid Bearer token; 2) Call GET /api/v1/dossiers/{victim_id}/access; 3) Receive access grants if v1CanAccess is bypassed",
"confidence": "med",
"notes": "Exposes access control metadata, not health data directly"
},
{
"ID": "AUTHZ-VULN-05",
"vulnerability_type": "Horizontal",
"externally_exploitable": true,
"endpoint": "GET /contact-sheet.webp/{id}",
"vulnerable_code_location": "/repos/inou-portal/api/api_contact_sheet.go:99,111",
"role_context": "authenticated user with any dossier access",
"guard_evidence": "Passes nil context to EntryGet(nil, series.ParentID) and DossierGet(nil, dossierID)",
"side_effect": "retrieve contact sheet images and patient names from other users' medical imaging studies",
"reason": "Explicitly passes nil to bypass authorization for parent study and dossier lookups",
"minimal_witness": "1) Login; 2) Discover valid series ID (via IDOR enumeration); 3) GET /contact-sheet.webp/{series_id}; 4) Receive image and patient name",
"confidence": "high",
"notes": "Portal proxy does no authorization - blindly forwards to API. API getAccessContextOrFail checks authentication but nil is passed to lookups"
},
{
"ID": "AUTHZ-VULN-06",
"vulnerability_type": "Horizontal",
"externally_exploitable": true,
"endpoint": "GET /api/v1/images/{id}",
"vulnerable_code_location": "/repos/inou-portal/api/api_v1.go:635,655",
"role_context": "user with valid API Bearer token",
"guard_evidence": "Passes nil to EntryGet(nil, id) and ImageGet(nil, id, opts) - authorization check happens AFTER data retrieval",
"side_effect": "retrieve medical imaging files (DICOM, X-rays, MRIs) from other users",
"reason": "Authorization via v1CanAccess happens at line 640 AFTER EntryGet at line 635 - data already retrieved from database",
"minimal_witness": "1) Get valid Bearer token; 2) Enumerate entry IDs; 3) Call GET /api/v1/images/{entry_id}; 4) Authorization checked post-retrieval",
"confidence": "high",
"notes": "Post-authorization pattern - data read before permission check, potential for timing attacks even if check passes"
},
{
"ID": "AUTHZ-VULN-11",
"vulnerability_type": "Vertical",
"externally_exploitable": true,
"endpoint": "POST /dossier/{id}/trackers/respond",
"vulnerable_code_location": "/repos/inou-portal/portal/trackers.go:354-358",
"role_context": "user with PermRead (read-only access)",
"guard_evidence": "Only checks authentication (getLoggedInDossier), NO authorization check for PermWrite on target dossier",
"side_effect": "create tracker response entries in dossiers where user only has read access",
"reason": "Endpoint validates authentication but not PermWrite permission - any authenticated user can write tracker responses",
"minimal_witness": "1) Get PermRead access to victim dossier; 2) POST /dossier/{victim_id}/trackers/respond with tracker data; 3) Entry created despite lacking PermWrite",
"confidence": "high",
"notes": "CRITICAL: Allows read-only users to modify health data"
},
{
"ID": "AUTHZ-VULN-12",
"vulnerability_type": "Vertical",
"externally_exploitable": true,
"endpoint": "POST /api/entries",
"vulnerable_code_location": "/repos/inou-portal/api/api_entries.go:58-62",
"role_context": "authenticated user or localhost",
"guard_evidence": "Uses getAccessContextOrSystem which allows localhost bypass, no PermWrite validation before create/update/delete",
"side_effect": "create, update, or delete entries in any dossier without PermWrite permission",
"reason": "No permission check beyond authentication - lib.EntryModify and lib.EntryAddBatch have no authorization",
"minimal_witness": "1) Get authentication; 2) POST /api/entries with create/update/delete operations; 3) Operations succeed without PermWrite check",
"confidence": "high",
"notes": "CRITICAL: Complete write access bypass. Also localhost requests get SystemContext (full bypass)"
},
{
"ID": "AUTHZ-VULN-13",
"vulnerability_type": "Vertical",
"externally_exploitable": true,
"endpoint": "POST /dossier/{id}/permissions",
"vulnerable_code_location": "/repos/inou-portal/portal/main.go:1403-1442",
"role_context": "user with PermManage",
"guard_evidence": "No check that grantee != current user, no validation that granted permissions ⊆ grantor permissions",
"side_effect": "self-escalate by granting own account higher permissions, or grant permissions you don't have to others",
"reason": "Missing self-escalation prevention and permission subset validation",
"minimal_witness": "1) Get PermManage on a dossier; 2) POST /dossier/{id}/permissions with email=own email and op_d=1 to grant self PermDelete; 3) Escalation succeeds",
"confidence": "high",
"notes": "CRITICAL: Permission escalation vulnerability allows PermManage users to gain PermDelete and grant permissions they lack"
},
{
"ID": "AUTHZ-VULN-14",
"vulnerability_type": "Vertical",
"externally_exploitable": true,
"endpoint": "DELETE /dossier/{id}/files/{fileId}/delete",
"vulnerable_code_location": "/repos/inou-portal/portal/upload.go:282-287",
"role_context": "user with PermWrite (but not PermDelete)",
"guard_evidence": "Checks CanEdit (PermWrite) instead of PermDelete",
"side_effect": "delete uploaded medical files without having PermDelete permission",
"reason": "Endpoint claims to require PermDelete but actually only checks CanEdit which maps to PermWrite",
"minimal_witness": "1) Get PermWrite access to dossier; 2) DELETE /dossier/{id}/files/{file_id}/delete; 3) File deleted despite lacking PermDelete",
"confidence": "high",
"notes": "Permission escalation from PermWrite to PermDelete for file deletion operations"
}
]
}