Vulnerability Module
IDOR and Auth Bypass: Detection and Remediation Guide
April 11, 2026 · 11 min read · PolyDefender Research Team
Endpoints that trust client-supplied IDs without server-side ownership checks allow any authenticated user to access any other user's data. How to find and fix every instance.
Insecure Direct Object Reference (IDOR) is the second most common critical vulnerability in AI-built applications after exposed credentials. In PolyDefender's closed-beta scan analysis, 27% of apps had at least one IDOR vulnerability on a user-data endpoint. Because IDOR allows reading other users' data through normal authenticated requests — no special tools required — it is one of the most practically exploitable vulnerabilities a web app can have.
How IDOR Happens in AI-Generated Code
When an AI tool generates a CRUD endpoint, it correctly handles the mechanics of the operation: parse the request, extract the record identifier, query the database, return the result. The step that is most often missing is the ownership check: before returning the record, verify that the requesting user owns it.
This is not a mistake unique to AI-generated code — it is one of the most common vulnerabilities in hand-written code too. But AI tools compound the problem because they generate dozens of handlers from the same pattern, and if the pattern lacks an ownership check, every generated handler has the same vulnerability.
The Attack in Practice
An IDOR attack requires no special tools or technical expertise. An attacker creates a legitimate account in your application, performs a normal operation (viewing their own profile, accessing their own order), intercepts the HTTP request in browser DevTools or a proxy, changes the resource ID to a different value, and resubmits. If the server returns data for the modified ID, the vulnerability is confirmed.
From there, the attacker can iterate through ID ranges (1, 2, 3, ... or UUIDs harvested from previous responses) to enumerate other users' data. Because the requests use a valid authentication token and look identical to legitimate requests, this attack is difficult to detect without careful anomaly monitoring.
Step 1: Identify All IDOR-Vulnerable Endpoints
An IDOR vulnerability exists anywhere that a resource ID flows from the client to a database query without a corresponding user ownership check. Review every handler in your application that accepts an ID parameter:
- ▸GET /api/orders/:orderId → fetches an order by ID without checking order.user_id === session.userId
- ▸GET /api/users/:userId/profile → fetches a profile by ID without checking userId === session.userId
- ▸PUT /api/documents/:documentId → updates a document without checking document.user_id === session.userId
- ▸DELETE /api/items/:itemId → deletes an item without checking item.user_id === session.userId
To identify these programmatically: search your codebase for patterns where a request parameter (params.id, req.params.userId, request.body.itemId) is used directly in a database query without a corresponding session user check in the same function.
Step 2: The Correct Fix Pattern
The fix is always the same: derive the user's identity from the authenticated session, then add an ownership check to the query.
Incorrect (vulnerable): const order = await db.orders.findOne({ where: { id: params.orderId } })
Correct (safe): const order = await db.orders.findOne({ where: { id: params.orderId, userId: session.userId } })
If the second query returns null, respond with 403 Forbidden — not 404, which reveals that the record exists under a different owner. A 403 response tells the attacker their ownership check failed without revealing anything about the record itself.
Step 3: Use Supabase RLS as a Defense-in-Depth Layer
For Supabase-backed applications, correctly written RLS policies provide a database-level defense against IDOR even if an application-level ownership check is accidentally missed. An RLS policy of USING (auth.uid() = user_id) means that even if your handler forgets the ownership check, the query will return zero rows for records owned by other users.
This is defense-in-depth, not a replacement for application-level ownership checks. Both layers should be present.
Step 4: Test Every Endpoint
Create two test accounts. For every endpoint that handles user-owned data:
- ▸Create a resource as user A (note the resource ID)
- ▸Authenticate as user B
- ▸Make a request to the endpoint using user A's resource ID
- ▸Confirm the response is 403 (or returns no data), not the resource content
Add these as automated integration tests in your CI pipeline. They should run on every deployment.
Auth Bypass: When Authentication Itself Fails
Auth bypass is distinct from IDOR — it occurs when an endpoint that requires authentication can be accessed without a valid session at all. Common patterns in AI-generated code: a middleware that checks authentication on route registration but not on individual handlers, a JWT validation function that handles the error case by returning null and allowing the request to proceed, or a session check that only runs on GET requests but not POST/PUT/DELETE.
- ▸Test every API endpoint from outside your app with no authentication header — confirm all user-data endpoints return 401
- ▸Check your middleware order — authentication middleware must run before the handler, and must call next() only on success
- ▸Review error handling in your JWT/session validation code — errors should reject the request, not default to allowing it
Need a fast security baseline?
Run a free scan to detect secrets, auth bypass, RLS exposure, injection paths, and dependency risk in minutes.