A security assessment CLI for AI-built ("vibe-coded") web apps.
You shipped an app with Lovable, v0, Cursor, Bolt, or Replit. The AI wrote a clean happy path — and quietly skipped authorization. The bugs that actually hurt aren't CVEs a scanner catches; they're authorization-logic holes:
- an endpoint that returns everyone's data with no login,
- a Supabase/Firebase table left world-readable because Row-Level Security was never turned on,
- a logged-in user who can read or change another user's records by changing an ID,
- a signup form that quietly accepts
role=admin, - an admin-only endpoint that answers anyone on the internet,
- a payment webhook that treats a forged "payment succeeded" as real,
- open self-registration behind a cosmetic "invite only" gate,
- a pre-signed upload URL anyone can write to,
- a websocket that reads and writes production records without a token,
- a login token the server will accept even when it's forged.
Kill-Ur-Vibe is an autonomous agent (bring your own Anthropic key) that probes an app you own or are authorized to assess, reasons about who the server trusts, proves the holes with real requests, and produces a consultant-grade report. Every finding leads with the plain-language harm ("what could go wrong, and who's hurt") so a non-technical founder gets it at a glance — while keeping the precise terms (each explained on first use) and the exact evidence an engineer or AI needs to fix it.
⚠️ Authorized targets only. This is an active-assessment tool. Point it only at systems you own or have written permission to test. It is built to make unauthorized use hard — every request is scope-gated in code — but the authorization is your responsibility.
- Single egress policy engine — the agent has no raw network. Every request (recon, probe, DNS, scan) is checked against the authorized scope at call time. An out-of-scope host or off-scope redirect is refused, not followed.
- Writes are synthetic, gated, and consented. The default run enables the
synthetic-write classes (account-create / object-PUT / websocket-save) for depth — but
only after a mandatory per-run authorization confirmation, and every write is gated
per action class, creates clearly-tagged synthetic records, and is never destructive.
Type
READ-ONLYat the prompt to run purely read-only. - No secret or PII values in reports. Findings record presence / type / count / length only; a redaction pass scrubs the output.
- Bounded. Hard caps per run — by default ~400 tool calls / 20 min wall-clock / ~$6
spend (tunable via
KUV_MAX_REQUESTS/KUV_MAX_WALL/KUV_MAX_USD); once any cap is hit, further requests are refused and the agent stops with a partial, honest report. - Deterministic where it matters. Severity comes from a rule table, not the model; JWT-role / source-map / secret-prefix judgments come from deterministic decoders.
The fastest way — an interactive wizard:
pip install -e .
kuvIt asks for your Anthropic key (hidden input, never saved to disk), the site you want
to check, and an explicit authorization confirmation — then runs a read-only
assessment and drops a PDF report on your Desktop. For automatic PDF it uses a
headless Chrome if you have one, or pip install '.[pdf]' for a bundled renderer.
Prefer to drive it yourself? Install, test, and try the bundled local vulnerable fixture (touches only localhost, reproduces a real authorization bug):
python3 -m venv .venv && . .venv/bin/activate
pip install -e '.[dev]'
pytest -q
export ANTHROPIC_API_KEY=sk-ant-...
python assess_fixture.pyAssess your own app via a scope file that defines what's in bounds:
# scope/myapp.yaml (gitignored)
engagement_id: myapp
authorized_by: you@example.com
targets: [ "app.example.com", "*.example.com" ]
expires_at: "2027-01-01"
allowed_actions: [] # read-only; add classes to permit synthetic writes
is_fixture: false
authorization_asserted: truepython assess.py https://app.example.com/ scope/myapp.yamlIt writes a polished HTML report to runs/ (open it, Cmd-P → Save as PDF).
Twenty-six gated tools — no shell, no raw network. Every request is scope-, SSRF-, and budget-checked in code, and every severity comes from a deterministic rule table, never the model. The agent fingerprints the stack first, then branches into the probes that stack unlocks, so the report reflects what your app actually runs instead of one generic sweep.
Recon & mapping
fingerprint_stack— structural tech detection (framework / CMS / BaaS / hosting / payment / auth) that drives everything belowdiscover_paths— routes/endpoints from the page + its JS bundles (optional path wordlist)render_page— headless-browser render of a JS SPA; reports its real runtime XHR/API endpoints, true backend origin, client-side routes, and websockets — every browser request egress-gated, off-scope abortedenumerate_subdomains— DNS subdomain enum + dangling-CNAME takeover, plus a security-header / CORS / TLS posture sweep of every live hostscan_js— full-bundle secret scan (keys / tokens / JWTs / DB URIs); returns type + count only, the bundle never enters the model's context
Exposure & posture (deterministic)
templated_checks— curated safe single-GET exposure library: served.env/.git/ backups, Spring actuator / phpinfo / mod_status, public OpenAPI — content-matched so an SPA's 200-for-everything shell is never a false hitcheck_http_posture— CSP / cookie / CORS / HSTS gapscheck_tls— certificate validity / expiry / hostname / protocolcheck_email_auth— SPF / DMARC (email-spoofing exposure)check_source_map— exposed source mapscors_credentialed— reflected arbitrary Origin + credentials (any website can read a logged-in user's data) — the case a static header check misses
Auth & token analysis (deterministic decoders)
decode_jwt_role— JWT role /alg=none/ forgeabilityclassify_secret— public-by-design key vs a real leakanalyze_oauth— authorize-URLstate/ PKCE /hd
Authorization & capability probes
probe_api_unauth— unauthenticated sweep of every discovered/v1|/api|/graphqlroute (incl. generic?q=search variants) — the/v1/search-style bypass, caught deterministicallybackend_rls— a BaaS (Supabase / Firebase / PocketBase / Appwrite) data API readable with no auth (Row-Level Security not enforced) — fires only on genuinely sensitive data, not a public-by-design tablefunc_authz— a privileged/admin function reachable with no login (broken function-level authorization)mass_assignment— an API that accepts injected privileged fields — confirmed by reading the record back, never on an echo alonewebhook_sig— a payment webhook that doesn't verify signatures (a forged "payment succeeded" is accepted), proven by a signed-vs-bogus-signature differentialuser_enum— a login/signup that reveals which emails have accounts (synthetic identifiers only — never a real user's email)ssrf— a URL parameter the server fetches and reflects (response-reflected SSRF)probe_websocket— unauthenticated websocket read/write with a values-free field summaryerror_leak— framework debug / stack-trace pages left on in productionhttp_get(passive read) ·http_write(synthetic write, gated per action class) ·record_finding
Every finding carries value-free evidence (status, counts, field names — never row values, secrets, or PII), and a run that hits its budget is flagged coverage-incomplete rather than presented as a clean bill.
The synthetic-write tier (self-registration, object-PUT, websocket-save, webhook/SSRF
probes) is ON by default to prove write paths — clearly-tagged synthetic records, never
destructive, still per-class gated, and only after the per-run authorization confirmation.
Type READ-ONLY at the prompt to run purely read-only.
Built and unit-tested (455 tests): egress policy engine + authorization scope (with a Public-Suffix-List registrable-domain helper and connect-time IP pinning), deterministic decoders + severity rules, the Claude Agent SDK harness, the secret scanner, DNS recon + per-host posture sweep, the unauthenticated API-endpoint sweep, the websocket / HTTP-posture / OAuth / TLS probes, the keystone-gated headless-browser render probe, structural stack fingerprinting + the curated exposure library, the stack-specific capability probes (no-RLS backend reads, unverified payment webhooks, mass-assignment, broken function-level authorization, credentialed CORS, user enumeration, response-reflected SSRF, verbose-error disclosure), and the report generator. Deferred: none of the core probe classes — expansion only.
The finding vocabulary is open: common authorization-bug classes (broken object-level access / IDOR, privilege-escalation, mass-assignment, forgeable tokens, SSRF, open-redirect) are first-class with deterministic severities, and a genuinely novel class the tool can't auto-rate is still recorded — flagged for operator triage, never silently dropped and never given an LLM-guessed severity. Generalization is measured on a held-out fixture suite (bug classes the method is taught for, on apps whose endpoints it has never seen), not on the one fixture it was built against.
Python 3.11+, Claude Agent SDK (Anthropic), dnspython, httpx. BYO Anthropic key.
MIT
0 comments
log in to comment.