Disclosure: the author works at HACKBOX PTE. LTD., which builds HackBox — referenced once below, in the section on autonomous decision-making. Everything else here is a technical argument you can test yourself.
Broken access control has held the top spot in the OWASP Top 10 since 2021, and it kept it in the 2025 edition — OWASP's own data puts it in 3.73% of the applications it tested. As of 2026 it is still the vulnerability class that automated testing reports least often. That combination is not bad luck — it is a property of how payload-based testing works, and it is the first thing to check when you evaluate whether a tool is actually testing your application or just checking its surface.
Here is the version of the bug that shows up in almost every web app I have seen tested:
GET /api/invoices/1043 HTTP/1.1 Host: app.example.com Cookie: session=eyJhbGciOi... # account 1043's own session Now change one digit:
GET /api/invoices/1044 HTTP/1.1 Host: app.example.com Cookie: session=eyJhbGciOi... # still account 1043's session HTTP/1.1 200 OK Content-Type: application/json {"id":1044,"account_id":8871,"billing_address":"...","amount":4820} That is a cross-tenant data leak, and nothing in the request is malformed. The session is valid, the path is a real endpoint, the method is correct, there is no injection string, no traversal, no anomalous header. A WAF sees a well-formed GET with a legitimate cookie and lets it through, because at the protocol level it is indistinguishable from normal traffic.
Why matchers can't see it
Most automated detection is built on one loop: send a request, compare the response against an expected signature, record a match. That loop is fast and it works well for a large class of bugs — the ones that announce themselves.
Access control violations don't announce themselves. Catching one requires three operations a matcher cannot perform:
- Build an identity model. Know which account owns resource 1044, and which resources account 1043 is entitled to reach.
- Cross the boundary on purpose. Request a resource outside that entitlement using a valid session — not a crafted payload.
- Judge the result semantically. Decide whether the response body constitutes a violation. A 200 with a JSON object is not automatically a leak; a 403 is not automatically a control working.
# roughly what step 3 has to do, and why a signature cannot do it def is_violation(request, response, owner_map): obj = parse(response.body) if obj is None or response.status != 200: return UNKNOWN # not evidence either way actual_owner = owner_map.get(obj.get("account_id")) return VIOLATION if actual_owner != request.session.account_id else OK The hard part isn't the comparison — it's having owner_map at all. That map is application-specific. It comes from crawling, from object-ID patterns, from watching what a user can legitimately reach. A scanner that only knows "there is an id parameter here" has nothing to compare against, so it reports "possible IDOR" and moves on. At scale, that note is indistinguishable from noise, which is why it ends up unfixed.
The OWASP Web Security Testing Guide documents the manual version of this workflow in detail. Knowing the steps was never the bottleneck. Executing them across thousands of objects, again after every deploy, is.
What changes when the engine picks the next step itself
The interesting shift in AI-assisted testing is not throughput. It is that the engine stops executing a branch structure written in advance and chooses its next action at run time from what it has already observed.
Concretely, that changes three things you can test for:
Identity-aware probing. If the engine can hold a model of "account A can reach X, account B can reach Y", it can generate the boundary-crossing requests itself instead of waiting for a human to notice the candidate.
Iterative exploitation. A matcher tests an endpoint and closes the case. An engine that decides its own path treats a confirmed finding as a new starting position: what is reachable from this session now, what does that access unlock, is there an object I can reach that I could not reach a minute ago.
Lateral movement. Nobody remembers the first finding. They remember the fourth, which they could only reach because of the third, on a machine that had no business being reachable from the internet at all. Staying in the environment after the first hit is what makes a report say "this server reaches the billing database" instead of "this server has a flaw".
That last capability is the one that matters for access control, and it is the design HackBox is built around: an engine that carries a model of what it has already reached, instead of closing a ticket when a signature matches. To be clear about scope — this is a property of how the engine is built, not a claim that autonomous testing finds every authorisation bug. It finds the ones whose boundary can be inferred from observed behaviour, which is most object-level IDOR and far from all business-logic abuse.
Verification is the part that decides whether anyone fixes it
Every team has received a report with 300 findings where 40 were real. The usual response is not to fix the 40 — it is to stop reading the reports.
Verification is a different operation from detection: send the payload, confirm the effect actually occurred, keep the evidence. In the example above, verification is not "the response had 200 and a JSON body". It is: the response contained account_id: 8871 while the session belonged to 1043, and here is the request, the response, and the field that proves it.
Findings that carry evidence fall into three states, and the third one matters more than most tools admit:
| State | Meaning | What to do with it |
|---|---|---|
Verified | Confirmed in this environment | Schedule normally |
Exploited | Exploit succeeded, impact demonstrated | Treat as urgent — impact is proven |
Manual Collaboration | Verification passed, exploitation evidence unclear | Engineer review before spending budget |
A tool with no third state is optimizing for a clean dashboard rather than for accuracy. When you evaluate anything in this category, ask how many findings it refused to confirm.
Vendors in this category tend to quote a false positive rate around 5% or below, self-reported. Treat any such number as a claim and test it against an application you already know well.
A 20-minute evaluation you can run yourself
If you are comparing tools, skip the feature matrix and run this against a staging app with two accounts at different privilege levels:
- Two-account object test. Log in as A, request an object owned by B. Does the tool attempt it without being pointed at the endpoint?
- Post-finding behavior. After a confirmed hit on a host, does it continue — enumerate what the new access reaches — or does it write the row and move on?
- Evidence check. Open one finding. Do you get payload, request, response, and the extracted proof? Or a severity badge?
- Uncertainty routing. Ask how many findings were downgraded to human review in the last 30 days. Zero is a warning, not a feature.
- Internal reach. Can it get to a host with no internet route? Cloud-only testing cannot see your internal database, whatever the dashboard says.
FAQ
Can automated testing find IDOR at all?
Yes — when the engine reasons about identity and ownership instead of matching payloads. It needs to know who owns what object, attempt the cross-tenant request with a valid session, and judge whether the response is a violation. That is a different operation from signature scanning, and it is the cleanest way to tell the two apart in a demo.
Does this replace a human pentest?
No. It replaces the repeatable part — reconnaissance, verification, regression after each deploy — and does it far more often than a human engagement can. Business logic flaws, chained authorization bugs across multiple services, social engineering, and bespoke exploitation still need a person. Any vendor claiming otherwise has not run a real engagement.
How often should it run?
Tied to deployment events, not to a calendar. A quarterly cadence reproduces the same gap annual testing already has.
Disclosure, again, because it belongs at the end too: the author works at HACKBOX PTE. LTD., a cybersecurity company headquartered in Singapore, which builds HackBox — an AI-powered automated penetration testing SaaS platform that runs the full attack chain (reconnaissance, exploitation, privilege escalation) against a target and returns a verified report. It is sold either by confirmed result or by IP subscription.
Website: https://www.hackbox.ai · Contact: partners@hackbox.ai
