Security Education

6 min

IDOR vulnerabilities: what they are, what they look like, and why they keep showing up in AI-built apps

IDOR vulnerabilities: what they are, what they look like, and why they keep showing up in AI-built apps

What IDOR actually means, a concrete example of how it works, why AI-generated code is particularly exposed to it, and how it gets caught during a security audit.

What IDOR actually means, a concrete example of how it works, why AI-generated code is particularly exposed to it, and how it gets caught during a security audit.

IDOR comes up fairly regularly in the access control and API security work I write about here, and based on the questions I get it’s worth its own dedicated explanation, because the term itself doesn’t really communicate what the problem is or why it matters.

IDOR stands for Insecure Direct Object Reference. That doesn’t make it much clearer. What it actually describes is a situation where your application lets a user access someone else’s data just by changing a number.


The concrete version

You build an app where users can view their invoices. When a user views invoice number 1042, the URL looks like this: /invoices/1042. The backend fetches that invoice from the database and returns it.

The question IDOR testing asks is: what happens when that same user changes the URL to /invoices/1043? Does the backend check whether invoice 1043 belongs to the person asking for it, or does it just fetch and return whatever ID it receives?

In a vulnerable app, the backend just fetches and returns it. Which means any authenticated user can work through invoice numbers sequentially and read every invoice in the system. No special tools, no sophisticated attack, just changing a number in a URL.

This applies to any resource that has an identifier the user can see or influence: orders, messages, profiles, uploaded files, support tickets, payment records, anything. The attack surface scales directly with how much data your app manages.


Why it’s the number one finding class in vibe coded apps specifically

IDOR has sat at the top of the OWASP Top 10 under Broken Access Control since 2021, and it predates AI coding tools by decades. What has changed isn’t the vulnerability class itself, it’s the volume of apps being shipped relative to the number being reviewed by someone who knows what IDOR is.

When an AI tool generates an API endpoint that fetches a record by ID, it generates the part that makes the feature work. The ownership check, the bit that says “also verify this record belongs to the authenticated user making the request”, is a separate piece of logic that requires understanding the intended access model of the application. AI tools don’t have that context unless it’s been explicitly prompted for, and even then it doesn’t make it in reliably.

The result is a very consistent pattern: the app works correctly for normal use, every user sees their own data, nothing seems wrong. The problem only surfaces when someone deliberately asks for data that isn’t theirs, which doesn’t happen in normal use and doesn’t get caught in standard QA.

In March 2025, a researcher named Matt Palmer was testing a LinkedIn profile generator built on Lovable. He removed an authorization header from one of the API requests, resent it, and got back what looked like the platform’s entire user database including names, email addresses, and private prompts users had written. He and a colleague then ran the same style of check against 1,645 apps Lovable was showcasing on its own marketplace. 170 of them, roughly one in ten, were leaking user data through the same class of flaw. That’s IDOR at scale, and the underlying cause was simply that the ownership checks weren’t there.


The ID format doesn’t make it safe

A fairly common response when this comes up is “but our IDs are UUIDs, not sequential numbers, so you can’t just guess them.” Worth addressing directly: UUIDs do make enumeration harder, but they don’t fix the underlying problem. If an attacker can obtain another user’s UUID through any other route (a shared link, a leaked API response, a separate information disclosure issue elsewhere in the app), the IDOR is still fully exploitable. The ID format affects discoverability, not the vulnerability itself.

The fix is always the same regardless of ID format: the server needs to verify ownership on every request, not just that the user is authenticated, but that this specific user is authorized to access this specific resource.


How it gets caught

IDOR is one of the vulnerability classes where automated scanning genuinely falls short, and this is worth knowing if you’re relying on one. A scanner can confirm that an endpoint exists and returns a 200. What it can’t do is determine whether the data in that response belongs to the user who requested it, because that requires understanding the intended access model of the application and reasoning about whether it’s been violated.

Manual testing for IDOR involves creating two separate accounts, performing actions under account A to generate resources with known IDs, then switching to account B and attempting to access those same resources. If account B can read, modify, or delete resources that belong to account A, that’s a confirmed finding. The same process gets repeated for any elevated privilege levels: standard user attempting to access admin functions, free tier user attempting to access paid features.

It’s a straightforward test to run once you know to run it. The issue is that most founders don’t know to run it, and the app gives no indication during normal use that there’s anything wrong.

Back to blog