
Table of contents
17
By Salman Khan, OSCP+, Founder of XHack, SRT (Synack Red Team member)
Read this in 30 seconds: IDOR testing with AI means using an agent to find places where your API lets one user reach another user’s data, and the safest and most useful way to do it is on an API you own, with test accounts, as a regression test you can run on every release. I read OWASP’s guidance and two research papers on 10 November 2026, and tested a small two-account check against a local demo API. This guide is for developers, security teams and authorised testers, and it deliberately has no payloads and no scripts that attack live systems.
- The flaw is common and the fix is a check on every object. OWASP ranks broken object level authorization as API1:2023, says it is “extremely common”, and says every endpoint that receives an object ID and acts on the object needs an object-level authorization check.
- A scanner does not know who owns what. The ownership rules live in your business logic, so IDOR testing with AI starts with you writing down who should be able to read which object.
- IDOR testing with AI helps in three places. It reads code for missing checks, turns an API spec into a test matrix and writes the regression tests, and research systems such as BACFuzz (16 of 17 known issues and 26 new ones across 20 PHP apps) show the direction.
- A two-account check is the core of IDOR testing with AI. My script sends only GET requests, refuses hosts you have not listed, and on a local demo flagged 3 of 6 checks as failing on a vulnerable build and 0 of 6 on the fixed one.
- XHack runs the browser-side half of IDOR testing with AI for you. Its web application testing compares what a logged-in user sees with what an anonymous visitor sees, with screenshot evidence, from $20 a month with a 7-day trial.
If you searched for IDOR testing with AI, you probably want to know whether an agent can find the bugs where one customer can read another customer’s records. It can help, but the version that works in practice looks less like an attack and more like a good test suite.
This IDOR testing with AI guide covers the idea, the rules, where an AI agent earns its place, a tested two-account check and the fixes OWASP recommends. I did not run a paid agent against a real API, so the research figures are the papers’ own and the script result is from a local demo I built.

For IDOR testing with AI, the target is simple: an IDOR, or insecure direct object reference, is a bug where an application uses an ID supplied by the user to fetch an object without checking that the user is allowed to have it, and BOLA is OWASP’s name for the same class of bug in APIs. PortSwigger’s Web Security Academy describes IDOR as one example of many access control mistakes, mostly leading to horizontal privilege escalation, where a user reaches another user’s data at the same privilege level.
OWASP’s API Security Top 10 (2023 edition) lists it first, as API1:2023 Broken Object Level Authorization. Its description says object IDs can be sequential numbers, UUIDs or strings, that they are easy to spot in the path, query string, headers or body, and that the issue is common because the server relies on client-sent IDs to decide which objects to fetch. Our BOLA and IDOR guide covers the definitions and the difference between the two terms, and the OWASP API Security Top 10 guide covers the rest of the list.
For IDOR testing with AI, test only systems you own or are explicitly authorised to test, and use accounts you created. Testing for access flaws means requesting objects that belong to other accounts, so the data you touch must be test data.
In IDOR testing with AI, an agent is useful for the reading and the bookkeeping, and not for deciding what the ownership rules are. The table splits the work.
| Task | Does AI help? | Where you stay in charge |
|---|---|---|
| Find endpoints that take an object ID | Yes, from an OpenAPI spec or the route code | Confirming the list is complete |
| Review handler code for a missing ownership check | Yes, it reads fast across files | Judging whether the check really covers the object |
| Build a test matrix of endpoint by user by expected result | Yes | Defining who should be allowed, which only you know |
| Write the regression tests | Yes | Reviewing them and keeping them in CI |
| Run tests against production | No | Never |
| Decide that a response is a leak | Partly | Checking the data really belongs to someone else |
| Explain a finding and suggest a fix | Yes | Verifying the fix with the test |
The pattern is the same as in our other agent guides: every row the agent can do is a row you can check quickly. Our Claude Code bug bounty guide covers keeping an agent inside a permission-controlled sandbox.
Published IDOR testing with AI work shows LLMs helping with the two hard parts of authorization testing, which are producing valid test requests and knowing whether a response is a real leak.
| Source | What it did | Reported result |
|---|---|---|
| BACFuzz, arXiv, 21 July 2025 | Grey-box fuzzer for broken access control in PHP apps, with LLM-guided parameter selection, runtime feedback and a SQL-based check on whether unauthorised input reaches a protected operation | On 20 apps, it detected 16 of 17 known issues and found 26 previously unknown ones with low false positives, all responsibly disclosed |
| BOLABuster, Palo Alto Networks Unit 42, 12 August 2024 | Uses an LLM to generate BOLA test cases from an OpenAPI 3 spec, and orders them so a delete test does not break later tests | Reported previously unknown BOLA flaws in three open-source projects: Grafana, Harbor and Easy!Appointments |
Read them with care. BACFuzz is a research tool that works on PHP applications, and BOLABuster is a vendor write-up of its own method. Neither is a product I tested, and neither tells you how an agent performs on your API. What they do show is why the design matters: the spec gives the agent the endpoints, and a runtime check, such as a SQL oracle or a two-account comparison, gives it ground truth so it is not guessing from a response’s look.

The core of IDOR testing with AI is a simple question asked in code: can user B read an object that belongs to user A? This script asks it for each pair of test users and each object, using GET requests only.
It has three safety features on purpose. It refuses to run against any host you have not added to ALLOWED_HOSTS, it sends only GET requests, and it prints status codes and never response bodies.
"""Object-level authorization regression check for an API YOU own.
It asks: can user B read objects that belong to user A? It only sends GET requests,
prints status codes (never response bodies) and refuses to run against hosts you have
not listed. Use it on a local build or a staging copy with test accounts, never on
production data and never on systems you do not own or have written permission to test.
Usage: python3 authz_check.py config.json
"""
import json, sys, urllib.error, urllib.parse, urllib.request
ALLOWED_HOSTS = {"localhost", "127.0.0.1"} # add your own staging host here on purpose
def get(url, token):
req = urllib.request.Request(url, headers={"Authorization": f"Bearer {token}"}, method="GET")
try:
with urllib.request.urlopen(req, timeout=10) as r:
return r.status
except urllib.error.HTTPError as e:
return e.code
def main(path):
cfg = json.load(open(path))
base = cfg["base_url"].rstrip("/")
host = urllib.parse.urlparse(base).hostname
if host not in ALLOWED_HOSTS:
sys.exit(f"refusing to run: {host} is not in ALLOWED_HOSTS")
users, failures, checks = cfg["users"], 0, 0
for ep in cfg["endpoints"]:
for owner, odata in users.items():
for oid in odata["owns"].get(ep["resource"], []):
url = base + ep["path"].replace("{id}", str(oid))
own = get(url, odata["token"]) # control: the owner can read it
checks += 1
if own != 200:
print(f"CONTROL FAILED {ep['path']} id={oid} owner={owner} status={own}")
failures += 1
continue
for actor, adata in users.items():
if actor == owner:
continue
status = get(url, adata["token"])
checks += 1
verdict = "ok " if status in (403, 404) else "FAIL"
failures += verdict == "FAIL"
print(f"{verdict} {actor} -> {owner}'s {ep['resource']}/{oid}: HTTP {status}")
print(f"\n{checks} checks, {failures} failing")
return 1 if failures else 0
if __name__ == "__main__":
if len(sys.argv) != 2:
sys.exit("usage: authz_check.py <config.json>")
sys.exit(main(sys.argv[1]))
I tested it against a small demo API I wrote that listens only on localhost, with two users and three orders. On the vulnerable build, the check reported 3 of 6 checks failing, because each user could read the other’s orders. On the fixed build, which returns 404 for objects the caller does not own, it reported 0 of 6 failing, and the script exited with an error when I pointed it at a host that was not on the list.
The config is a small JSON file with your base URL, two test users with tokens, the object IDs each one owns and the endpoint templates. A passing result means “not found” or “forbidden” came back for the other user’s object, and a failing result means the status was 200.

This is the part of IDOR testing with AI where an agent saves time. Give your agent the OpenAPI spec and ask for a first draft:
Here is the OpenAPI spec for our API (staging). List every endpoint that takes an object ID
in the path, query or body. For each, say which resource it returns and who should be allowed
to read it (owner, admin, anyone). Output a table, then a JSON config for authz_check.py.
Do not call the API. Mark anything you are unsure about.
Review the table before you trust it. The agent cannot know your ownership rules unless the spec or the code says them, so every “who should be allowed” cell is a question for you.

The fix for what IDOR testing with AI finds is an authorization check in every function that uses a client-supplied ID, and a test that keeps it there. OWASP’s prevention guidance for API1:2023 says:
OWASP also warns that comparing the user ID in the session token with the ID parameter is not a sufficient solution and handles only a small subset of cases. Ownership can involve teams, shared documents and delegated access, so the check has to follow your real rules.
Return the same response for “not yours” and “does not exist” where you can, as the demo’s fixed build does with 404, so the response does not confirm that someone else’s object exists. Then keep the two-account IDOR testing with AI check in CI so a refactor cannot quietly remove the check.

So yeah, here is where we talk about our own product. I am biased, it is my company, and I think XHack is the strongest all-in-one option for the browser-side half of this work, for reasons you can check.
My script does IDOR testing with AI at the API level with two accounts. XHack’s web application testing covers the other half. The agent drives a real browser through your app and, according to its feature page, compares what your app shows a logged-in user with what it shows an anonymous visitor to spot broken access control and IDOR issues, then captures screenshots as evidence. Point it at a staging copy you own and describe the target in plain English.
XHack combines three things most providers sell separately: an autonomous AI agent, a continuous security platform and human testers.

Individual plans are $20, $49 and $150 a month, with a 7-day free trial, one per person. See the pricing page and the agent for bug bounty guide. Run it against a target you own and judge it by what it finds, because brutal honesty is kind of our thing.
Yes, as candidates. AI can find candidates and make the testing faster, but it needs ground truth to avoid guessing. In IDOR testing with AI, an agent reads the spec or code to list endpoints that take object IDs, drafts a test matrix and writes regression tests, and a two-account check confirms whether one user can reach another’s object. Research systems such as BACFuzz report good results, and you should still verify every finding yourself.
Use a local build or staging copy, test accounts you created, and read-only requests first. Request an object that belongs to one test user as the other test user, and a “not found” or “forbidden” answer means the check works. Never test with real users’ data, and get written permission for any system you do not own.
They describe the same flaw from two angles. IDOR is the older web term for using a user-supplied ID to reach an object without a check, and BOLA is OWASP’s API-specific name, ranked first in the 2023 API Security Top 10. Our BOLA and IDOR guide explains how the terms relate.
Because a scanner does not know which user should own which object. A response that returns valid data looks like success, and only your ownership rules say it is a leak. That is why IDOR testing with AI works best when you supply the rules and the test accounts.
Add an object-level authorization check in every function that uses a client-supplied ID, following your real ownership rules, and write a test that fails if the check is removed. OWASP also recommends random, unpredictable IDs, as a supplement and not a replacement, and warns that comparing the session user ID with the ID parameter is not sufficient on its own.
Only if the program’s scope and rules allow it, with accounts you created and no access to other users’ real data. Read the policy first, because some programs restrict automation and AI use, and report what you can prove with your own test accounts. Our AI bug bounty policy guide covers what platforms say.
IDOR testing with AI is most valuable when it feeds a regression test: write the ownership rules, let an agent draft the matrix and review the code, run a two-account check on every release and fix with an authorization check on every object.
Keep IDOR testing with AI to systems you own or are cleared to test, and keep the test in your pipeline so the fix stays fixed.
Categories
Related articles