Identifying IDORs
URL parameters and APIs
The first step is spotting direct object references in HTTP traffic. Look for:
- URL parameters:
?uid=1,?filename=file_1.pdf - API path segments:
/api/users/1/profile - Other headers: cookies, custom headers
In basic cases, increment the value (?uid=2) and check whether data belonging to another user is returned. Fuzz with thousands of variations to find hits β any successful access to resources that are not yours indicates an IDOR.
AJAX calls in front-end code
JavaScript-heavy applications may place all function calls in the front-end and selectively enable them based on user role. Admin functions are disabled for standard users but the code is still present and inspectable.
Example hidden AJAX call:
function changeUserPassword() {
$.ajax({
url: "change_password.php",
type: "post",
dataType: "json",
data: {uid: user.uid, password: user.password, is_admin: is_admin},
success: function(result) { }
});
}
This function may never fire for a non-admin user, but finding it in the source reveals the endpoint, parameters, and direct object references (uid). Test these references manually β if the back-end executes the call without role validation, it is vulnerable.
This applies to any function, not just admin-level ones. Review front-end JS for endpoints not visible through normal HTTP traffic.
Encoded references
Some applications encode or hash object references instead of using sequential integers. This does not provide security if there is no back-end access control.
Base64-encoded references
If a parameter looks like Base64 (e.g., ?filename=ZmlsZV8xMjMucGRm):
- Decode it β
file_123.pdf - Modify the plaintext β
file_124.pdf - Re-encode β
ZmlsZV8xMjQucGRm - Request with the new value β if it returns data, IDOR confirmed
Hashed references
A parameter like ?filename=c81e728d9d4c2f636f067f89cc14862c looks secure at first glance. Check the front-end source for the hashing logic:
$.ajax({
url: "download.php",
type: "post",
dataType: "json",
data: {filename: CryptoJS.MD5('file_1.pdf').toString()},
success: function(result) { }
});
If the hash is just MD5(filename), compute hashes for other filenames and request them. If the algorithm is not visible in the source, use hash identifier tools to guess it, then verify by hashing a known value and comparing.
Comparing user roles
For advanced IDOR testing, register multiple accounts and compare their HTTP requests and object references side by side. This reveals:
- How unique identifiers are calculated
- Which API parameters differ between roles
- Whether the back-end validates the callerβs session against the requested data
Example: User1 can view their salary via:
{
"attributes": {
"type": "salary",
"url": "/services/data/salaries/users/1"
},
"Id": "1",
"Name": "User1"
}
User2 may not see this endpoint in their UI, but if they replay the same API call (changing the ID), and the back-end only checks for a valid session β not whether the session matches the requested resource β the data is returned. Even if the parameters for other users cannot be calculated, finding that the back-end lacks this check is itself a vulnerability worth documenting.