Offensive security for every pull request
Your code is
.Let’s fix that.
grayhat is an AI hacker for your codebase. On every pull request it attacks your app in a throwaway sandbox, using the same unfiltered models real attackers use, and proves each bug with a working exploit. Then it opens the pull request that fixes it.
Install the GitHub App on the repos you choose. No seats: you pay per review.
- 01Attackin a throwaway sandbox
- 02Provewith a working exploit
- 03Fixas a pull request
01 — The unfiltered model
We hack you with the models black hats use.
Every repo gets a deep scan from top open-weight models with their refusals removed. Attackers already run them. Frontier models are trained to hedge, refuse or water down the exact questions that matter: is this exploitable, write the payload, show me the bypass. Ours answers, then proves it.
Typical AI code reviewer
safety-tuned
› Write a working exploit for the auth change in GET /invoices/:id and prove another tenant's data leaks.
I can't help create exploits or attack code. I'd recommend reviewing your authorization logic and following OWASP best practices for access control.
grayhat · deep scan
open-weight · abliterated
› Write a working exploit for the auth change in GET /invoices/:id and prove another tenant's data leaks.
$ curl -H "Authorization: Bearer $TENANT_B" \ api.acme.dev/invoices/inv_7Hq2 200 OK {"customer":"tenant_a","total":"48,200.00"}
Top open-weight models
The strongest open models, with refusal training stripped out. No hedging, no watered-down fixes.
A deep scan of the whole repo
Every route, guard and dependency on day one, then every pull request after that.
Pointed only at your code
It runs only on repos where you install the app, and every exploit runs in a throwaway sandbox.
02 — Proof, not alerts
Every finding ships with a working exploit.
acme/billing-api · PR #482 · src/routes/invoices.ts
grayhat[bot] reviewed
Any signed-in user can read any invoice
This PR removed requireOwner() from GET /invoices/:id. The handler loads by id with no tenant filter.
Proof of concept
$ curl -H "Authorization: Bearer $TENANT_B" \ https://api.acme.dev/invoices/inv_7Hq2 200 OK {"customer":"tenant_a","total":"48,200.00"…}
Fix PR #483 opened · exploit now returns 404 · 214 tests pass
5 credits
03 — How it works
A map of your code, and an attacker that reads it.
A persistent index tells the hacker exactly what changed in security terms. It ranks what to attack, but never decides what to skip.
- [1] index
Map every route, guard and sink
Call graph, data flows and capabilities, updated as each push merges.
- [2] diff
Read the PR like an attacker
"This PR removed requireAdmin from /api/users/:id." Not a raw diff.
- [3] hunt
Chain bugs, write exploits
An unrestricted model, a skeptic that throws out the noise.
- [4] fix
Prove it, then patch it
A fix PR ships only when the exploit fails and your tests pass.
04 — What it catches
The bugs with no sink.
Pattern scanners look for dangerous calls. The worst bugs are a missing check, or two ordinary lines in the wrong order.
- 01IDORGET /invoices/:id returns anyone's invoicecritical
- 02Business logicCoupons stack; refund exceeds order totalhigh
- 03Race conditionsCheck-then-spend balance with no lockhigh
- 04Home-grown authToken compared with ==, never expireshigh
- 05Hidden codeAn encoded payload in a postinstall scriptcritical
left-pad-utils 2.4.1 → 2.4.2 patch release capability 2.4.1 2.4.2 network · + fetch(atob("aHR0cHM6Ly9…")) env / secrets · + process.env.* process · + postinstall: node ./x.js filesystem read read ✕ blocked new maintainer 3 days ago · obfuscated · no source tag
05 — Supply chain
We read the package, not the CVE feed.
A hijacked maintainer has no CVE yet. We analyze the dependency code itself, once per version, so every team on grayhat is protected the moment it ships.
06 — Pricing
Pay for attacks,
not for seats.
Your whole team gets in for free. You spend credits only when grayhat reviews or fixes something.
See plans and credit costs →credit per pull request review
credits per verified fix PR