Every check we run

Every check we run, and what it takes to turn it RED. Nothing here is a score.

ai

AI-DISC-001coverage-only (never emitted as a finding)
AI/chat endpoint discovered

coverage-only (never emitted as a finding; listed so the catalogue documents what discovery feeds COST-001/AI-INJ-002)

AI-INJ-002live
System prompt or hidden instructions leak via prompt injection

AMBER; RED if leaked text contains a secret

Proven by: 1 canned payload, max_tokens<=200, only on endpoints already proven anonymous

AI-MCP-003live
MCP/tool config runs unpinned or piped commands

AMBER (supply-chain via agent tooling)

api

API-DBG-001live
Debug details in production

AMBER (RED if stack contains secret)

API-DOCS-001live
API documentation is public

AMBER (RED if the classifier finds a secret literal inside)

API-DBG-002live
Debug/config endpoint exposes internal settings

AMBER, evidence is key names only; RED if the classifier finds a recognised secret literal inside

API-CORS-001live
CORS allow-all with credentials

AMBER (RED if data API + PII proof)

API-GQL-002live
GraphQL introspection exposed

AMBER

API-UPLOAD-003catalogued, not yet live
Unrestricted file upload

AMBER (RED if executable + public URL)

auth

AUTH-ADMIN-001live
Admin endpoint without authentication

RED if /admin* anon 200 with sensitive content

AUTH-MASS-002live
Self-editable role (mass assignment)

RED if role escalates via PATCH (throwaway account)

AUTH-RATELIMIT-003catalogued, not yet live
No rate limit on login/reset

AMBER (RED if combined with credential stuffing surface)

Proven by: <=15 reqs/30s, abort on 429

AUTH-SESSION-004catalogued, not yet live
Session survives logout/password change

AMBER (static+M2 dynamic where safe)

authz

SUPA-BOLA-002live
Another user can read this record

RED on A->B proof with throwaway users

Proven by: A/B harness + cleanup

cost_abuse

COST-001live
Anonymous expensive AI endpoint

RED only when the endpoint echoes our nonce (proven spend); AMBER if it answers anonymously but the nonce is unconfirmed

Proven by: tiny max_tokens<=16, nonce echo required for RED, <=3 reps

COST-002catalogued, not yet live
User-controlled model/max_tokens without cap

AMBER (RED if anon + top-tier model selectable)

dependencies

DEP-REACH-001live
Reachable critical CVE in prod path

AMBER default; RED only if reachable + exploit path (Trivy/OSV + call graph)

firebase

FB-RTDB-001live
Firebase Realtime Database readable without login

RED if anonymous GET /.json?shallow=true returns a non-empty object (proven)

Proven by: 1 request, shallow only, key names in evidence, never values

infra

INFRA-EXP-001live
/.env exposed

RED on 200 + KEY= pattern

INFRA-EXP-002live
/.git exposed

RED on ref: match

INFRA-MAP-003live
Source maps expose original code

AMBER (RED if secret inside)

INFRA-HDR-001live
Content-Security-Policy missing

AMBER (hygiene; never RED)

INFRA-HDR-002live
HSTS missing

AMBER (hygiene; never RED)

INFRA-HDR-003live
Clickjacking protection missing

AMBER (hygiene; never RED)

INFRA-SURF-001live
Bot protection blocked the scan

AMBER, and every other check is reported as NOT_checked (a challenge page is never graded)

payments

PAY-001live
Stripe webhook without signature verification

RED-capable static: missing constructEvent (no live charge test)

PAY-002live
Client-controlled amount/price

RED-capable static: amount from req.body without Price-ID allowlist

regrets

OPS-BACKUP-001catalogued, not yet live
Backups off / restore never tested

AMBER max (Things you will regret later)

secrets

SEC-007live
Supabase service_role exposed in frontend

RED if service_role JWT in bundle (bypasses RLS)

SEC-HIST-007-stripelive
Stripe secret key in client bundle

RED if sk_live_* in shipped JS

SEC-008-openailive
OpenAI key in client bundle

RED (unbounded spend)

SEC-009-anthropiclive
Anthropic key in client bundle

RED

SEC-HIST-003live
Secret in git history

RED until rotated (history is forever)

SEC-013live
NEXT_PUBLIC secret-like assignment

AMBER (confirm reachability)

SEC-015-telemetrylive
Telemetry/analytics key exposed (Sentry DSN, PostHog, Datadog client token)

AMBER, confidence low — these keys are public by design, verify scope; never RED

SEC-016-datadog-apilive
Datadog API key exposed

RED — the API key (not the client token) can read/write org-wide monitoring data

SEC-014live
Secret committed in MCP/agent config

RED (config files are read by every agent run)

supabase

SUPA-RLS-001live
Table readable without authorisation (RLS off)

RED if anon reads PII/financial rows (dynamic proof)

Proven by: anon GET /rest/v1/<table>, <=5 reqs, throwaway data only

SUPA-RLS-002live
Overly broad policy USING(true)/tautology

RED if anon/auth reads cross-user rows

Remediation: USING(auth.uid()=user_id) + down-migration

SUPA-WRITE-004live
Anonymous can write rows (missing INSERT/WITH CHECK)

RED if anon INSERT succeeds on user table

SUPA-STORAGE-005catalogued, not yet live
Storage bucket publicly readable

RED if private object anon-readable

SUPA-RPC-006catalogued, not yet live
Unprotected RPC/edge function callable anonymously

RED if sensitive RPC anon 200

SUPA-DEFINER-007live
SECURITY DEFINER without search_path/auth

AMBER (RED if search_path hijack + data exfil path)

Machine-readable: /checks.json