IDOR (Insecure Direct Object Reference)

All about IDOR vulnerability

Root Cause:

  • Access control is not properly implemented

Incorrect Way
$user_id = $_GET['uid'];
$user_info = get_user_info($user_id);
Correct Way
$user_id = $_SESSION['uid'];
$user_info = get_user_info($user_id);
  • References to data objects (like a file or a database entry) are predictable (user_id=1234,user_id=1235) (weak uid have low entropy)

Finding IDOR Attack Vectors Ideas:

  1. What do they use for authorization?(JWT, API Keys, cookies, tokens) Tip: Find this out by replacing high privilege authorization with lower privilege authorization and seeing what the server responds with

  2. Understand how they use ID's, hashes, and their API. Do this by looking at the API Documentations if they have one.


  1. Edit/ Delete others users data

  2. Disclose sensitive info

  3. Reset any users password

  4. And many more...

Recon for IDOR's:

  • Try to search engine scrape for UUIDs, ex: google dork for IDOR URL parameters ( inurl: id=)

  • Use burp extension autorize / autorepeater

  • To find URL parameters for endpoints, use tools like Arjun to bruteforce common IDOR URL parameter names.

  • Using tools like WaybackURLS or gau, and grep for UUID's, ids and common IDOR URL parameters

  • Scraping JS files for API endpoints with UUID's, common IDOR parameters

  • Filter Burp hisory to gather different ids through likely parameter names (id, order, email, profile, key, user, edit, number, account etc)

Note: Recon for IDORs is very hard, many of them are found manually using logic and they depend on each application highly. To add onto this, IDOR's are commonly found on API endpoints with JSON parameters, not URL. However, IDOR recon is still good to possibly find some low-hanging fruit.

💡Tip: Don't blindly test for changing numbers till you get PII, tools can do this for you. Dive deep into applications, find hidden functionality and features, and know how your application works most of all to succeed in finding IDOR's.

Every time you see a new API endpoint that receives an object ID from the client, ask yourself the following questions:

  • Does the ID belong to a private resource? (e.g /api/user/123/news vs /api/user/123/transaction)

  • What are the IDs that belong to me?

  • What are the different possible roles in the API?(For example — user, driver, supervisor, manager)

Common Bypasses and Tips

IDOR Techniques
  • Bypassing Object Level Authorization:

Add parameters onto the endpoints for example, if there was

GET /api_v1/messages --> 200
GET /api_v1/messages?user_id=victim_uuid --> 200

Why Does this Work?: Sometimes the applications authorization settings are not set to directory level, or the whole URL, making it so that adding URL parameters can bypass previous restrictions to certain endpoints.

Note: To find URL parameters for endpoints, use tools like Arjun to bruteforce common IDOR URL parameter names.

  • HTTP Parameter pollution

GET /api_v1/messages?user_id=VICTIM_ID --> 401 Unauthorized
GET /api_v1/messages?user_id=ATTACKER_ID&user_id=VICTIM_ID --> 200 OK
GET /api_v1/messages?user_id=VICTIM_ID&user_id=ATTACKER_ID
GET /api_v1/messages?user_id=YOUR_USER_ID[]&user_id=ANOTHER_USERS_ID[]

Why Does this Work?: The logic behind this is that component that performs the authorization check and the endpoint, they both use different libraries to parse query parameters. So In some cases, library #1 would take the first occurence of “user_id” while library #2 would take the second one.

  • Add .json to the endpoint, if it is built in Ruby!

/user_data/2341 --> 401 Unauthorized
/user_data/2341.json --> 200 OK
  • Test on outdated API Versions

/v3/users_data/1234 --> 403 Forbidden
/v1/users_data/1234 --> 200 OK

Why Does this Work?: Developers usually leave the non-productive version of the API vulnerable. (Non - productive can be testing/ beta/ earlier versions of the API)

  • Wrap the ID with an array.

{“id”:111} --> 401 Unauthriozied
{“id”:[111]} --> 200 OK
  • Wrap the ID with a JSON object:

{“id”:111} --> 401 Unauthriozied
{“id”:{“id”:111}} --> 200 OK
  • JSON Parameter Pollution:

POST /api/get_profile
Content-Type: application/json
  • MFLAC:

GET /admin/profile --> 401 Unauthorized
GET /ADMIN/profile --> 200 OK

Why Does this Work?: In some cases administrative backends which are usually protected by login functions are also protected with things like .htaccess or access rulesets, but they can also be misconfigured.

  • Path Traversal:

POST /users/delete/VICTIM_ID --> 403 Forbidden
POST /users/delete/MY_ID/../VICTIM_ID --> 200 OK
  • Replace HTTP request method with GET/POST/PUT/DELETE/PATCH

GET /users/delete/VICTIM_ID --> 403 Forbidden
POST /users/delete/VICTIM_ID --> 200 OK

Why Does this Work?: Sometimes, applications will only enforce access control only on one HTTP request method. so it'll forget to implement the same access controls across all other HTTP request methods.

  • Replace non-numeric with numeric ID's

GET /file?id=90ri2xozifke29ikedaw0d
GET /file?id=302

Random Tips/Tricks:

  • Don’t ignore encoded and hashed IDs. If the application is using a hashed/ randomized ID, see if the ID is predictable

  • Try to send a wildcard(*) instead of an ID. It’s rare, but sometimes it works.

  • Check through the same corresponding mobile API endpoints for the webapp, to find uuids, if you need them to complete the IDOR exploitation

  • Many times there will be endpoints to translate emails into GUID's, check for those

  • If it is a number id, be sure to test through a large amount of numbers, instead of just guessing Ex: Burp intruder from ID 100-1000

  • If endpoint has a name like /api/users/myinfo, check for /api/admins/myinfo

  • Replace non-numeric with numeric ID's

  • Try changing the request's Content-Type (Content-type: application/xml → Content-type: application/json)

  • Do not give up on error messages

  • If none of these work, get creative and ask around!

Escalating/Chaining with IDOR's Ideas:

  1. Lets say you find a low impact IDOR, like changing someone elses name, chain that with XSS and you have stored XSS! (Stealing other user's session through XSS)

  2. If you find IDOR on and endpoint, but it requires UUID, chain with info disclosure endpoints that leak UUID, and bypass this!

  3. PII

  4. Account Takeover (Change email address/ passwords/ security questions of a user)

  5. If none of these work, get creative and ask around!

Mitigation Strategies:

  • Implement proper access control mechanism

  • Use high entropy id values


References/ Interesting Reads: