VANDAMAdversarial App Audit
Verified security findings.Code fixes included.
A focused security review of your application. For each verified finding, you receive steps to reproduce the issue, the affected code and a proposed fix, together with the checks behind the report.
$4,800 one week
Can one customer open another customer’s order?
GET /api/orders/1043signed in as customer 311
404 Not Found
- Browsercustomer 311
- APIorders route
- Ownership checkadded
- Orders
1041customer 3111042customer 3111043customer 287
Any signed-in customer can read any order.
The route loads an order by its number and never compares the order’s owner with the person signed in. Changing 1042 to 1043 in the address returns another customer’s order, with name, address and items.
GET /api/orders/1043 session: customer 311200 OK order 1043 · customer 287 · 3 items
Look the order up within the signed-in account.
const { id } = req.paramsconst order = await db.orders.find({ id })const order = await db.orders.find({ id, customerId: session.customerId })if (!order) return notFound()
orders.test.tsregression test
passedanother customer’s order returns 404
passedyour own order still opens
One missing check is the most common flaw on the web.
- #1
- Broken access control tops the
OWASP Top 10, the security industry’s standard list of web app risks, 2025. - #1
- Reading another customer’s record by changing an ID tops the
OWASP API Security Top 10, rated easy to exploit and widespread. - $10.22M
- average cost of a data breach in the US, a record.
IBM, Cost of a Data Breach, 2025.

Our research shows models are getting better at coding accurately but are not improving at security.
So no, code that passes its tests can still show one customer another’s data.
Give engineering something it can act on.
A security report that says access control is weak leaves engineering with the real work still to do: find where it fails and decide what to change. A useful finding names the request that breaks it, the code responsible and the fix.
We test sign-in, data access, storage and payments within an agreed scope, the places where one missing check exposes another customer’s records. Every issue is reproduced, then rechecked before it reaches the report. Your engineers get the reproduction, the affected files, a proposed code change and a test that shows the hole is closed.
What engineering works through.
One list of findings, each reproduced before it reaches you. A finding opens on the request that breaks the check, the response it returned, the file and line responsible and the proposed change. Nothing in the list is a guess, and nothing asks your team to repeat our testing to believe it.
Engineers assign a finding, apply the change and mark it ready. We rerun the original reproduction against the fix, together with the test that shows your own records still open. When a release changes the routes we tested, the team sends a retest request naming the release and the findings it touches.
What every report contains.
Your application differs. The structure of the report does not.
Scope record
The environment, accounts and features we agreed to test, and what stayed out.
Access map
Who can sign in, which records each role can reach, and how storage and payments are handled.
Misuse cases
The realistic attempts we made against each boundary, including the ones that held.
Reproduction
The request or action that demonstrates each finding, run more than once.
Affected code
The files and lines responsible, so an engineer can go straight to them.
Proposed fix
Replacement code with the location and the reason for the change.
Regression test
A test that shows the hole is closed and that legitimate access still works.
Review record
The scope, evidence and checks behind the report, kept together.
From a suspected issue to a reviewed fix.
Agree and map the scope
We identify the application boundaries to review, including who can sign in, which records they can access and how storage and payments are handled. Testing stays within the agreed environment and scope.
Scope - Sign-in · email + Googlein scope
- Customer recordsin scope
- File storagein scope
- Payments ·
Striperead only
Reproduce the finding
We test realistic misuse cases and recheck any suspected issue. A finding includes the request or action that demonstrates it and the relevant files, so another engineer can follow the evidence.
Finding 03 · reproduced GET /api/invoices/8812signed in as: customer A- -
200 OK · returns customer B’s invoice file: api/invoices/[id].ts, line 14
Deliver the code change
We prepare replacement code with the location and reason for the change. The review record keeps the original reproduction, supporting evidence and checks together so your team can assess the fix.
Fix · api/invoices/[id].ts - -
const invoice = await db.invoice.find(id) - +
const invoice = await db.invoice.find({ id, - +
ownerId: session.user.id }) - +
if (!invoice) return notFound()
- -
Tested this week.
Retested after each release.
The report describes your application as it was during the audit week. Every release can add a route or remove a check, so after delivery we can rerun the reproductions and test what changed.
Fix verification
We rerun the original reproduction against each fix your team ships, and record the result in the finding.
Release retests
Before or after a release, we retest the findings and routes it touches.
New scope
New roles, routes, storage or payment flows reviewed with the same method as the first audit.
Check-ins
A short session with engineering on open findings, accepted risks and what the next release changes.
What you
receive.
Verified findings
Reproduced issues linked to the relevant files and lines.
Code fixes
Replacement code for the findings we verify.
Review record
The scope, evidence and checks behind the report.
Where the audit leads.
Each next step has its own service.
Developers with an AI assistant wrote significantly less secure code, and were more likely to believe it was secure.
Stanford study by Perry, Srivastava, Kumar and Boneh, 2023
Before you ask.
Do you test on our production system?
We agree the environment and the test accounts before we start, and testing stays inside them. Anything outside the agreed scope is left alone.
What if you find nothing serious?
The report says so. The review record shows what we tested and how, so the result can be checked.
Do our engineers apply the fixes?
Yes. We deliver replacement code with the location and reason for each change, and your team reviews and merges it.
Can we share the report in a customer’s security review?
The report is yours to share. It covers the scope we agreed and says so, which matters if the customer asks about other parts of your system.
