Insecure Direct Object References

Check List

Methodology

Black Box

1

Create two accounts if possible or else enumerate users first

2

Check if the endpoint is private or public and does it contains any kind of id param

3

Try changing the param value to some other user and see if does anything to their account

4

change HTTP method like this

GET /users/delete/victim_id -> 403
POST /users/delete/victim_id -> 200
5

Try replacing parameter names instead of this

GET /api/albums?album_id= <album id>
6

Try This

Tip: There is a Burp extension called Paramalyzer which will help with this by remembering all the parameters you have passed to a host

GET /api/albums?account_id= <account id>
7

Path Traversal IN users Path

if request like this

POST /users/delete/victim_id -> 403
8

change request to this

POST /users/delete/my_id/..victim_id -> 200
9

change request content-type

Content-Type: application/xml
Content-Type: application/json
10

swap non-numeric with numeric id

GET /file?id=90djbkdbkdbd29dd
GET /file?id=302
11

Missing Function Level Acess Control and changes Charachter path

GET /admin/profile -> 401
GET /Admin/profile -> 200
GET /ADMIN/profile -> 200
12

send wildcard instead of an id

GET /api/users/user_id 
changes to this
GET /api/users/*
13

Never ignore encoded/hashed ID for hashed ID ,create multiple accounts and understand the pattern application users to allot an iD

14

Bypass object level authorization Add parameter onto the endpoit if not present by defualt

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

HTTP Parameter POllution Give mult value for same parameter

GET /api_v1/messages?user_id=attacker_id&user_id=victim_id
GET /api_v1/messages?user_id=victim_id&user_id=attacker_id
16

change file type

GET /user_data/2341 -> 401
GET /user_data/2341.json -> 200
GET /user_data/2341.xml -> 200
GET /user_data/2341.config -> 200
GET /user_data/2341.txt -> 200
17

json parameter pollution

{"userid":1234,"userid":2542}
18

Wrap the ID with an array in the body

{"userid":123} -> 401
{"userid":[123]} -> 200
19

c wrap the id with a json objec

{"userid":123} -> 401
{"userid":{"userid":123}} -> 200
20

Test an outdata API version

GET /v3/users_data/1234 -> 401
GET /v1/users_data/1234 -> 200

Delete Account (IDOR)

1

Log in to your own account in two browsers A and B with User A and User B

2

Create your own *Licenses and certifications in both the account

3

Create your own *Licenses and certifications in both the account

4

Now In the body change the ID number and you will be able to delete all the Licenses and certifications present in HackerOne

5

For now change the ID to the Licenses and certifications ID of the Other account and it will be deleted.


Unsubscribe IDOR

1

Go to the subscribe page and sign up with an email (or create two test emails)

2

Note the subscribe URL: ...?p=subscribe&id=

3

Change subscribe → unsubscribe: ...?p=unsubscribe&id=1

4

In the unsubscribe form enter the target email (for example, the email you previously subscribed with)

5

The page shows “You have been unsubscribed...” and a confirmation email is received (The report indicates this works without CAPTCHA or a confirmation link)


GraphQL IDOR

1

Capture the GraphQL UpdateCampaign POST request when editing a campaign (example request sent to POST /graphql with JSON body containing input.campaign_id)

2

The campaign_id is a base64-encoded global id (e.g. Z2lkOi8vaGFja2Vyb25lL0NhbXBhaWduLzI0NA==gid://hackerone/Campaign/244 when decoded)

3

Change the numeric ID part of the decoded GID (e.g. 244243 or 245), re‑encode the modified GID to base64 and replace input.campaign_id with that value in the same request

4

Send the modified UpdateCampaign request. The server accepts the request for the targeted campaign_id (even if that campaign belongs to another program), allowing the campaign to be updated/removed via that request

5

Impact: by targeting another program’s ongoing campaign id, a requester can modify or delete campaigns they don’t own

Key detail: decode campaign_id from base64 → you get gid://hackerone/Campaign/<N>Modifying <N> and re-encoding changes the target campaign. idor lead to view private reports title,url,id,state,substate,severity_rating,readable_substate,created_at,submitted_at,reporter_name


Account Deletion IDOR

1

Create two test accounts: victim@test and attacker@test. Ensure you control both

2

From the victim account, initiate an account-delete flow in your browser while intercepting requests (Burp/DevTools) to capture the JSON body that would be sent (this reveals the body format; do not forward the request). Example body contains email and authPW

3

Cancel the actual request so no deletion occurs

4

Log in as attacker and prepare a new POST /v1/account/destroy request in an interceptor/repeater. Replace the body with the victim’s captured email and authPW values (only for your test accounts). Send the request only if both accounts are test accounts you control

5

Observe server response: if the server returns success and the victim account is deleted, the vulnerability is confirmed. Prefer to confirm by checking server response codes and deletion flags rather than deleting real production data


GraphQL IDOR

1

allows to modify the links of any user. Users can put their custom links or social media links on their profile

2

Replicate the following request by replacing it with your own authentication headers

3

must also put in the body of the request, in the parameter "username" the username that you want, you can try my username: "criptexhackerone1". This request will return in the response the links of any user profile with the "id" of each link. for example

POST / HTTP/2
Host: gql.example.com

{"id":"11a239b07f86","variables":{"username":"*********"}}
4

When you get some "id" save it

5

In the next request you have to put in the request body, in the "id" parameter the previously saved id, you can also change the name and the link

POST / HTTP/2
Host: gql.example.com

{"id":"c558e604581f","variables":{"input":{"socialLinks":[{"outboundUrl":"https://www.hackerone.com","title":"hacker","type":"CUSTOM","id":"* * * * * * * * *  * * * * *  * * * * * * * * * *  * * * * *  *"}]}}}
6

Finally re-enter the victim's profile and you will see the modified links. It is important to mention that you may have to reload the page a few times or wait a few seconds

A real attacker can modify the name and content of any user's social links. It is important to add that social links are something main in user profiles, if an attacker exploits this with all reddit users it could be devastating


IDOR Broken Object Level Authorization

1

Login (attacker): Authenticate in the application with your test attacker account in a browser

2

Capture baseline request: Navigate to the profile endpoint and capture the request to

GET /api/v1/users/current? HTTP/1.1
3

Prepare modified request: In Repeater, modify the request path by replacing current? with a target identifier

GET /api/v1/users/$USERNAME HTTP/1.1
4

Send modified request: Send it from Repeater and inspect the HTTP response body

If the response returns JSON containing the target’s profile fields (e.g., full_name, username, github_username, website, created_at, id, photo, etc.), the endpoint leaks other users’ data

5

Verify with controlled accounts (recommended): For a safe PoC, create a second test account (victim-test), add a distinguishable field (e.g., bio: "victim-test-proof"), then repeat step 3 using that username — this proves read access without touching real users

6

Document evidence: Save/sanitize the HTTP request and response (redact cookies, Authorization headers, tokens and any PII you don’t own). Take a screenshot of the returned JSON (with sensitive fields redacted if needed). Note timestamps and user-agents

7

Do not brute-force: Avoid enumerating many usernames or automating tests on production. Limit yourself to 1–2 manual checks or use staging


Content Move IDOR

1

You can move your contents via Move to button at $WEB/dashboard

2

when you click to Move to > My Content you will send a POST request to /dashboard like that

3

$ACTIONABLE[] parameter's value is the content's ID. And if you change this ID to victim's content ID, you will see victim's content at My Content page

4

After sending the request through Burp Suite and changing the parameter, go back to the Mycontent section


1

Make two accounts one is for the victim and the other for an attacker

2

Add some featured images in both accounts. Go to Profile --> Add Profile Section --> Recommended --> Add Featured

3

Delete an image on the attacker's account and capture that request using burp and sent it to the repeater It makes a delete request like the one, given below

4

It takes consists of thress things ProfileId, and sectionUrn which also take same ProfileId value

5

Now visit the victim's profile featured images without logging in as the victim. Copy the link of the image you want to delete from the victim's profile, which looks like this

6

Paste that link into your notepad and notice that in this link, we got both ProfileId , ImageId. In the above link, I get these

7

Now simply replace the respected values of required parameters in the repeater and send a request

8

You see that the targeted featured image from the victim's profile was successfully deleted


IDOR in Update Profile Section

1

create An Account in web and go to Update Profile Section For example

https://example.com/UpdateProfile/<user-id>
2

Change the Numeric user-id to any other, and you'll see other user's email-addresses


File Download IDOR

1

Go to the site and wherever you see CSV file download and other extensions, activate the Interception section using Burp Suite

2

Click on download file and get the request

3

In the request, look for a parameter that has the word ID or is numeric

4

Manipulate the parameter and change the Id and send the response

5

If another file with other content including user information or sensitive information is found inside this downloaded file, it has IDOR vulnerability


White Box

Cheat Sheet

Last updated