The risky code your AI assistant wrote, found first.
PatchLabs Code reads your repo and every past commit: keys that should never have been committed, packages with published advisories, and the patterns AI-built apps get wrong, from open edge functions to unsigned payment webhooks. It reads; it never runs your code.
stripe.webhooks.constructEventAsync(body, sig, secret).How it works
Read, match, look up, report.
Pure static reading of the files in your repo, with a time budget, so a check never hangs on a large project.
Read
The working tree and the full git history, including commits that later deleted a key.
working tree + every commitMatch
Provider-specific key patterns and checks written for AI-built apps: edge functions, webhooks, admin pages, CORS, Firebase rules.
supabase/functions/** firestore.rulesLook up
Dependency versions from your lockfile, checked against the OSV advisory database. Offline, this step reports “skipped” instead of failing.
lockfile → OSV querybatchReport
Each finding gets an ID, file, line, short redacted evidence and a one-line fix.
PL-021 · high index.ts:4
Capabilities
13 Code checks live today.
Every check has a finding page with the vulnerable pattern and the fix.
AI, payment or database key in the code
A live key for an AI provider, Stripe, AWS or a database sits in your current code. Values are masked in the report.
Service role key in client code
The key that bypasses every rule is bundled into code that ships to the browser.
Key still in git history
An AI, payment or database key was committed once. Deleting the line didn’t delete it.
Edge function open without sign-in while using the service key
A function that skips the sign-in check but talks to the database with the key that bypasses every rule.
Sign-ups need no email confirmation
Anyone can create accounts with addresses they don’t own, which turns PL-002 into a public leak.
Access decided by user_metadata, which users can edit
Code or SQL that grants access from user_metadata, which every user can change about themselves. Reproducing it in the lab is coming.
Admin check only in the browser
The admin page hides itself in the frontend, but the data behind it is open to any signed-in user.
Payment webhook doesn’t verify its signature
A Stripe-style webhook trusts the request body, so anyone can post a fake “paid” event.
Edge function trusts a user id sent in the request
The function acts on whatever user id the caller sends instead of the signed-in user’s.
Dependency with a known vulnerability (OSV)
A package version in your lockfile with a published advisory, looked up in the OSV database.
User content rendered as raw HTML
dangerouslySetInnerHTML or innerHTML fed with user input, without sanitising it.
Firebase rules allow anyone
Firestore or Storage rules with allow read, write: if true, or open to every signed-in user.
Any website can call a signed-in function
A function answers CORS * while reading the caller’s auth, so other sites can act as your users.
Keys
A deleted key is still in your git history.
Git keeps every version of every file. If a key was ever committed to a public repo, anyone who clones it can find it, even after a later commit removed it. Every report links each key to the page where you revoke it.
Your Supabase anon key is public by design and isn’t flagged. What matters is the rules behind it, which PatchLabs Lab tests.
AI providers · by key format
Anthropic, OpenAI (including admin and service-account keys), OpenRouter, Google AI Studio and Cloud, Groq, Replicate, Hugging Face, Perplexity, xAI, Fireworks, ElevenLabs, DeepSeek, plus keys in variables named for about 30 more AI and data services.
Payments, database and platform
Stripe live secret and restricted keys, Supabase service_role, AWS access keys, GitHub and Slack tokens, Resend, Railway, credentials inside URLs, private key blocks.
Files
.env files committed now or ever. Example files such as .env.example and obvious placeholders are skipped.
Sample output
One finding, as the API returns it.
Every product line shares one finding shape, so your report, the API, webhooks and your CI read Code findings the same way as Lab findings.
- File and line, so your engineer goes straight to it
- Evidence is short and redacted: never a full key, never personal data
advisoryis filled for dependency findings (PL-023)
{
"id": "PL-021",
"line": "code",
"severity": "high",
"title": "Payment webhook doesn't verify its signature",
"object": "supabase/functions/stripe-webhook/index.ts",
"line_no": 4,
"evidence": "req.json() used without constructEvent",
"proven": false,
"fix": "Verify the Stripe-Signature header before trusting the body"
}
Static reading has limits. Code checks read patterns in your files; they don’t execute your app, so they can miss logic spread across services and can flag code that is safe for reasons outside the repo. Findings say what was matched so your engineer can judge. We don’t do dependency reachability analysis, DAST or pentests.
Do you run or build my code?
No. Code checks only read files. We never run your code, never install your packages and never call your app. The whole scan has a 120-second budget.
Where do dependency advisories come from?
From OSV, the open vulnerability database, queried with the package names and versions in your lockfile. If OSV can’t be reached, the check reports “skipped” rather than guessing.
Is my Supabase anon key a finding?
No. It ships in your app on purpose. The service_role key is different: in client code it bypasses every rule, which is PL-010.
Do Code findings get a lab-proven fix?
Lab findings get a migration proven as three identities. Code findings get a precise fix with the file and line; most are code changes your engineer makes, so they aren’t proven in the database lab. The report labels which is which.
Free check
Find what your AI assistant committed, before someone else does.
Paste your public repo. Code and Lab run together in every check.