Application security · starts with GitHub
Security monitoring that opens the pull request.
Connect GitHub. ShipLock reads your code, follows each entry point through to the data it can reach, and opens a fix for you to approve. Connect the rest of your stack when you want its live configuration checked too. No checklist to work through, and nothing to copy and paste.
Any signed-in user can read every workspace’s invoices.
Pull request opened, waiting for your approvalHow it works
Three steps, then it keeps going on its own.
01
It reads the repository
Every route handler, the schema, the imports. Your code already names your auth provider, your database and your payment webhooks, so we know what to check without asking you to describe it.
02
It works out what an attacker reaches
Starting at each entry point and following the guard: who can call this, what does it resolve about them, and does anything narrow the result to that person. Findings are paths, not line numbers.
03
It opens the pull request
On its own branch, never merged by us, and only after the change has been tested against the problem it fixes. Where the answer is a decision about your product, we say so instead of guessing.
Who it is for
Startups with customers and no security hire.
Small teams shipping quickly, where most of the code was written with an AI assistant and nobody has time to audit it by hand. Supabase and Postgres today; other databases after that.
What you get
What it actually does
Two halves: read everything, then prove one thing.
The first half runs on your repository alone. The second is what separates a finding you have to believe from one you can watch happen.
1 · It reads every layer, and joins them
One connection. None of these layers is a finding on its own. The join is.
Correlated. An authenticated route reads invoices without workspace_id. None of these layers says that alone.
2 · It attacks a copy, never your app
A disposable replica with synthetic tenants and none of your data.
1 row returned that should not exist. The leak is reproduced rather than inferred, and the fix is re-run against the same copy before it reaches you.
Reproduction needs your database connected. Reading the code does not.Why this class of bug, and not another
The failures we look for have already happened.
Every one of these is documented and linked. We are not describing a threat model we invented. We are describing what has repeatedly gone wrong in applications built the way yours was.
170+ live apps, one missing row policy
Applications generated by an AI builder shipped with row-level security absent on tables holding user records. Anyone with the public key could read every row. This is the exact shape of the first path our reasoner looks for.
Read the source →Broken object-level access is still the hardest to catch
A benchmark built specifically because ownership bugs resist pattern matching: the code looks correct in isolation and is only wrong relative to who is calling. It is why we reason over routes and schema together rather than grepping for a rule.
Read the source →Broken access control, still number one
The category has led the list across consecutive revisions, and it is the one a scanner is worst at, because the rule it breaks is specific to your product rather than to a language.
Read the source →More, with the reasoning written out: real incidents and how the OWASP categories map to what we check.
Point it at a repository.
The first audit takes a few minutes and tells you where you stand.
Get started