API logic vulnerabilities: why scanners miss IDOR and how it is actually found
The most expensive breaches of recent years are not exploits or 0-days but API logic flaws: swap in someone else's ID — get someone else's data. No scanner finds them out of the box, because from the code's point of view everything works correctly. Here is how this vulnerability class works and how it gets found.
What a logic vulnerability is
A logic vulnerability is when the application works exactly as coded, but not as the business intended. The classic examples:
- ◇IDOR (insecure direct object reference): the /orders/{id} endpoint checks that the user is logged in but not that the order is theirs. Enumerating IDs returns other people's orders, payments, documents.
- ◇Broken access control: a regular user calls an admin endpoint and it responds — because the role check exists in the UI but not in the API.
- ◇Mass assignment: the API accepts the whole JSON object, so a profile PATCH request can smuggle in role: admin or balance: 100000.
- ◇Workflow abuse: business process steps called out of order — confirming a payment without the payment, applying a promo code after cancelling the order.
Why scanners miss them
SAST looks for dangerous constructs in code, DAST for known signatures in responses. But IDOR has no dangerous construct and no signature: the request is well-formed, the response is valid JSON with status 200. Recognizing the leak requires context: this user should not see this object.
That is why logic flaws are traditionally found only by hand: a pentester reads the API, builds a model of who should see what, then methodically probes every endpoint under different roles and compares responses. For an API with a hundred endpoints that is days of monotonous work that still requires understanding — which is why real-world pentests usually sample the logic rather than cover it exhaustively.
How Izanagi automates this
Izanagi is our LLM-driven scanner for API logic vulnerabilities. It does what a pentester does, but with exhaustive coverage: reads the OpenAPI specification, builds hypotheses about the role model and object relationships, generates "own/foreign" request pairs under different accounts and compares responses. Every finding is a proven PoC: a concrete request, a concrete foreign object in the response.
The key difference from classic DAST is that the model understands API semantics: that orders belong to users, that an endpoint with put and a role field is a mass assignment candidate, that the "create → cancel → apply discount" chain is worth probing. A pilot runs on your staging environment in 2–4 weeks; the result is a report with a new/known/fixed diff against your previous pentests.
What your team can do right now
- ◇Authorization at the object level, not the endpoint level: not "the user is logged in" but "this user has access to this object". In every handler.
- ◇Field allowlists for writes: PATCH and PUT accept only explicitly permitted fields, never the whole object.
- ◇Foreign-object tests: for every endpoint, an automated test where user A requests user B's object and gets 403. A cheap and very effective CI safety net.
- ◇API inventory: logic holes most often live in forgotten endpoints — old versions, internal routes exposed externally, test paths.
FAQ
2–4 weeks on your staging environment: an exhaustive API logic sweep with a proven PoC for every finding. Scope and success criteria are fixed before the start.
Discuss a pilot