[{"id":"SEC-007","title":"Supabase service_role exposed in frontend","category":"secrets","severity_logic":"RED if service_role JWT in bundle (bypasses RLS)","auto_fix":false,"pr_allowed":true,"human_required":"key rotation","implemented":"live"},{"id":"SEC-HIST-007-stripe","title":"Stripe secret key in client bundle","category":"secrets","severity_logic":"RED if sk_live_* in shipped JS","auto_fix":false,"pr_allowed":true,"human_required":"rotation + refund audit","implemented":"live"},{"id":"SEC-008-openai","title":"OpenAI key in client bundle","category":"secrets","severity_logic":"RED (unbounded spend)","auto_fix":false,"pr_allowed":true,"human_required":"rotation + spend caps","implemented":"live"},{"id":"SEC-009-anthropic","title":"Anthropic key in client bundle","category":"secrets","severity_logic":"RED","auto_fix":false,"pr_allowed":true,"human_required":"rotation","implemented":"live"},{"id":"SEC-HIST-003","title":"Secret in git history","category":"secrets","severity_logic":"RED until rotated (history is forever)","auto_fix":false,"pr_allowed":false,"human_required":"rotation + purge guidance","implemented":"live"},{"id":"SEC-013","title":"NEXT_PUBLIC secret-like assignment","category":"secrets","severity_logic":"AMBER (confirm reachability)","auto_fix":false,"pr_allowed":true,"implemented":"live"},{"id":"SEC-015-telemetry","title":"Telemetry/analytics key exposed (Sentry DSN, PostHog, Datadog client token)","category":"secrets","severity_logic":"AMBER, confidence low — these keys are public by design, verify scope; never RED","auto_fix":false,"pr_allowed":false,"implemented":"live"},{"id":"SEC-016-datadog-api","title":"Datadog API key exposed","category":"secrets","severity_logic":"RED — the API key (not the client token) can read/write org-wide monitoring data","auto_fix":false,"pr_allowed":true,"human_required":"rotation","implemented":"live"},{"id":"SUPA-RLS-001","title":"Table readable without authorisation (RLS off)","category":"supabase","severity_logic":"RED if anon reads PII/financial rows (dynamic proof)","validation":"anon GET /rest/v1/<table>, <=5 reqs, throwaway data only","implemented":"live"},{"id":"SUPA-RLS-002","title":"Overly broad policy USING(true)/tautology","category":"supabase","severity_logic":"RED if anon/auth reads cross-user rows","remediation":"USING(auth.uid()=user_id) + down-migration","implemented":"live"},{"id":"SUPA-BOLA-002","title":"Another user can read this record","category":"authz","severity_logic":"RED on A->B proof with throwaway users","validation":"A/B harness + cleanup","implemented":"live"},{"id":"SUPA-WRITE-004","title":"Anonymous can write rows (missing INSERT/WITH CHECK)","category":"supabase","severity_logic":"RED if anon INSERT succeeds on user table","implemented":"live"},{"id":"SUPA-STORAGE-005","title":"Storage bucket publicly readable","category":"supabase","severity_logic":"RED if private object anon-readable","implemented":"catalogued, not yet live"},{"id":"SUPA-RPC-006","title":"Unprotected RPC/edge function callable anonymously","category":"supabase","severity_logic":"RED if sensitive RPC anon 200","implemented":"catalogued, not yet live"},{"id":"SUPA-DEFINER-007","title":"SECURITY DEFINER without search_path/auth","category":"supabase","severity_logic":"AMBER (RED if search_path hijack + data exfil path)","implemented":"live"},{"id":"AUTH-ADMIN-001","title":"Admin endpoint without authentication","category":"auth","severity_logic":"RED if /admin* anon 200 with sensitive content","implemented":"live"},{"id":"AUTH-MASS-002","title":"Self-editable role (mass assignment)","category":"auth","severity_logic":"RED if role escalates via PATCH (throwaway account)","implemented":"live"},{"id":"AUTH-RATELIMIT-003","title":"No rate limit on login/reset","category":"auth","severity_logic":"AMBER (RED if combined with credential stuffing surface)","validation":"<=15 reqs/30s, abort on 429","implemented":"catalogued, not yet live"},{"id":"AUTH-SESSION-004","title":"Session survives logout/password change","category":"auth","severity_logic":"AMBER (static+M2 dynamic where safe)","implemented":"catalogued, not yet live"},{"id":"API-DBG-001","title":"Debug details in production","category":"api","severity_logic":"AMBER (RED if stack contains secret)","implemented":"live"},{"id":"API-DOCS-001","title":"API documentation is public","category":"api","severity_logic":"AMBER (RED if the classifier finds a secret literal inside)","implemented":"live"},{"id":"API-DBG-002","title":"Debug/config endpoint exposes internal settings","category":"api","severity_logic":"AMBER, evidence is key names only; RED if the classifier finds a recognised secret literal inside","implemented":"live"},{"id":"API-CORS-001","title":"CORS allow-all with credentials","category":"api","severity_logic":"AMBER (RED if data API + PII proof)","implemented":"live"},{"id":"API-GQL-002","title":"GraphQL introspection exposed","category":"api","severity_logic":"AMBER","implemented":"live"},{"id":"API-UPLOAD-003","title":"Unrestricted file upload","category":"api","severity_logic":"AMBER (RED if executable + public URL)","implemented":"catalogued, not yet live"},{"id":"COST-001","title":"Anonymous expensive AI endpoint","category":"cost_abuse","severity_logic":"RED only when the endpoint echoes our nonce (proven spend); AMBER if it answers anonymously but the nonce is unconfirmed","validation":"tiny max_tokens<=16, nonce echo required for RED, <=3 reps","implemented":"live"},{"id":"COST-002","title":"User-controlled model/max_tokens without cap","category":"cost_abuse","severity_logic":"AMBER (RED if anon + top-tier model selectable)","implemented":"catalogued, not yet live"},{"id":"PAY-001","title":"Stripe webhook without signature verification","category":"payments","severity_logic":"RED-capable static: missing constructEvent (no live charge test)","implemented":"live"},{"id":"PAY-002","title":"Client-controlled amount/price","category":"payments","severity_logic":"RED-capable static: amount from req.body without Price-ID allowlist","implemented":"live"},{"id":"INFRA-EXP-001","title":"/.env exposed","category":"infra","severity_logic":"RED on 200 + KEY= pattern","implemented":"live"},{"id":"INFRA-EXP-002","title":"/.git exposed","category":"infra","severity_logic":"RED on ref: match","implemented":"live"},{"id":"INFRA-MAP-003","title":"Source maps expose original code","category":"infra","severity_logic":"AMBER (RED if secret inside)","implemented":"live"},{"id":"DEP-REACH-001","title":"Reachable critical CVE in prod path","category":"dependencies","severity_logic":"AMBER default; RED only if reachable + exploit path (Trivy/OSV + call graph)","implemented":"live"},{"id":"OPS-BACKUP-001","title":"Backups off / restore never tested","category":"regrets","severity_logic":"AMBER max (Things you will regret later)","implemented":"catalogued, not yet live"},{"id":"INFRA-HDR-001","title":"Content-Security-Policy missing","category":"infra","severity_logic":"AMBER (hygiene; never RED)","implemented":"live"},{"id":"INFRA-HDR-002","title":"HSTS missing","category":"infra","severity_logic":"AMBER (hygiene; never RED)","implemented":"live"},{"id":"INFRA-HDR-003","title":"Clickjacking protection missing","category":"infra","severity_logic":"AMBER (hygiene; never RED)","implemented":"live"},{"id":"AI-DISC-001","title":"AI/chat endpoint discovered","category":"ai","severity_logic":"coverage-only (never emitted as a finding; listed so the catalogue documents what discovery feeds COST-001/AI-INJ-002)","implemented":"coverage-only (never emitted as a finding)"},{"id":"AI-INJ-002","title":"System prompt or hidden instructions leak via prompt injection","category":"ai","severity_logic":"AMBER; RED if leaked text contains a secret","validation":"1 canned payload, max_tokens<=200, only on endpoints already proven anonymous","implemented":"live"},{"id":"AI-MCP-003","title":"MCP/tool config runs unpinned or piped commands","category":"ai","severity_logic":"AMBER (supply-chain via agent tooling)","implemented":"live"},{"id":"SEC-014","title":"Secret committed in MCP/agent config","category":"secrets","severity_logic":"RED (config files are read by every agent run)","auto_fix":false,"human_required":"rotation","implemented":"live"},{"id":"FB-RTDB-001","title":"Firebase Realtime Database readable without login","category":"firebase","severity_logic":"RED if anonymous GET /.json?shallow=true returns a non-empty object (proven)","validation":"1 request, shallow only, key names in evidence, never values","implemented":"live"},{"id":"INFRA-SURF-001","title":"Bot protection blocked the scan","category":"infra","severity_logic":"AMBER, and every other check is reported as NOT_checked (a challenge page is never graded)","implemented":"live"}]