Product · Security scanner
Five passes, in a box with the door welded shut.
Deterministic checks first, a model last and only over what they found. That order is why a finding here comes with a file and a line rather than a confident guess.
The passes
What each pass is looking for.
Each is a different kind of evidence with its own state. A stage that fails doesn't take the rest down — you get what ran, labelled, and no score rather than a misleading one.
- 01
Things you never meant to publish
Every key, token and password you ever committed — including the ones you deleted afterwards. Git keeps them, and so does anyone who cloned you.
500 commits deep · finds keys deleted months ago
- 02
Doors left unlocked
Pages that should sit behind a login and don't. Data one signed-in user can read that belongs to another.
Rules we wrote ourselves, tuned for Next.js
- 03
Borrowed code with known problems
Every package you installed, checked against the public record of known holes in them.
Offline, against a database shipped inside the scan
- 04
The parts that aren't code
Where your uploads live, who can read your database, whether your storage is open to the world. This is the part other scanners skip, and it is where vibe-coded apps leak.
The checks nobody else is writing
- 05
Then it gets explained
Only now does a model get involved, and only over what the four passes above already found. It groups duplicates, ranks by what an attacker could do, and writes it in plain English.
Same ranking on every plan, free included
Hardening
Four things that happen around the scan.
Most of the engineering here isn't the scanning. It's making sure a scan that failed cannot look like one that passed.
- 01
The clone goes deep, then goes quiet
Your repo is cloned 500 commits deep, with submodules left alone, and the access token is stripped out of the clone before anything else happens.
A one-commit clone cannot see a key you committed and deleted later — which is the exact case that matters most.
- 02
The network is cut, and the cut is proved
Network egress is cut, and then the cut is verified with a request that is supposed to fail. If it succeeds, the scan aborts and your credit is returned.
We never trust the API that performed the cut. A tool that silently cannot phone home returns nothing, and nothing looks exactly like a clean repo.
- 03
Everything after the cut works offline
Every scanner runs offline against data shipped inside the box. The vulnerability database has a date, and that date is printed on your report.
A stale database is a real limitation. An undated one is a lie by omission.
- 04
Then the box is destroyed
When the scanners finish, the box is destroyed. Your source is never written to our database and never appears in a log line.
Secrets we find are stored as a masked fingerprint and a location — never the literal value. Storing the key we just found would be worse than finding nothing.
The rule pack
The checks nobody else is writing.
We ship only rules we wrote and own — the big public sets are licensed for internal use only. Updated weekly.
The frontend checks who you are and the database does not, so the anon key reads the whole table
A service-role key shipped to the browser because it was the one that worked
An admin page that checks you are signed in, and never checks who you are
An upload bucket left public because that is how the tutorial had it
A webhook endpoint with no signature check, so anyone can post to it
None of these are exotic. They are what happens when a tool writes code that works, and nobody was ever told what to check afterwards.
Coverage
What we check, and what we cannot.
The honest version, including what we don't do yet.
Covered today, for JavaScript and TypeScript
Secrets and git history, dependency vulnerabilities, route protection, role checks, server/client boundary mistakes, unsafe rendering, storage rules and database row-level security read from committed migrations.
Reported as not checked, with instructions
Database and storage rules that live only in a hosting dashboard. If your Supabase project has no migrations in the repo, there is nothing for us to read, and we report exactly that instead of guessing.
Partly covered, and told so plainly
Python, Go, Ruby and the rest get the language-independent checks — secrets, dependencies, configuration — plus a plain statement of the coverage you did not get. Their own rule packs come later.
Run it against something you already shipped.
One repo, read-only, two scans a day on the free plan. No card, and nothing kept after the scan ends.