Skip to main content

index

Insecure Direct Object Reference (IDOR)

Insecure Direct Object References (IDOR) is a security vulnerability that occurs when an application allows users to directly access or modify objects (such as files, database records, or URLs) based on user-supplied input, without sufficient access controls. This means that if a user changes a parameter value (like an ID) in a URL or API request, they might be able to access or manipulate data that they aren’t authorized to see or modify.

Vulnerable Code

Look at the code snippet below, any logged-in user can access other users’ data by changing the user_id parameter in the URL.

To fix this, we need to check if the logged-in user owns the requested data.

<?php
// Assume user is already authenticated

// Get user ID from URL (e.g., profile.php?user_id=3)
$user_id = $_GET['user_id'];

// Fetch user data without checking ownership
$conn = new mysqli("localhost", "root", "", "users_db");
$result = $conn->query("SELECT * FROM users WHERE id = $user_id");

if ($result->num_rows > 0) {
$user = $result->fetch_assoc();
echo "Name: " . $user['name'] . "<br />";
echo "Email: " . $user['email'] . "<br />";
}
?>

MUST have Burp Extension

Autorize is an extension aimed at helping the penetration tester to detect authorization vulnerabilities, one of the more time-consuming tasks in a web application penetration test.

Short Note

Following color and their meaning when using this extension:

  1. Bypassed! - Red color
  2. Enforced! - Green color
  3. Is enforced??? (please configure enforcement detector) - Yellow color

Testing Methodology

Numeric Value Parameter

Increment and decrement these values to access sensitive information.

  • Decimal value: 287789, 287790, 287791, ...
  • Hexadecimal: 0x4642d, 0x4642e, 0x4642f, ...
  • Unix epoch timestamp: 1695574808, 1695575098, ...

Common Identifiers Parameter

Some identifiers can be guessed like names and emails, they might grant you access to customer data.

  • Name: john, doe, john.doe, ...
  • Role: customer, admin, moderator, ...
  • Email: email@gmail.com
  • Base64 encoded value: ZW1haWxAZ21haWwuY29tCg==

Weak Pseudo Random Number Generator

  • UUID/GUID v1 can be predicted if we know the time they were created: 95f6e264-bb00-11ec-8833-00155d01ef00
  • MongoDB Object Ids are generated in a predictable manner: 5ae9b90a2c144b9def01ec37
    • a 4-byte value representing the seconds since the Unix epoch
    • a 3-byte machine identifier
    • a 2-byte process id
    • a 3-byte counter, starting with a random value
info

Useful tool: https://github.com/andresriancho/mongo-objectid-predict

  • By default it predicts future OID than provided one.
  • Using --backward flag, it predicts previous/older OIDs.
  • --counter-diff 100 will generate 100 OIDs only around passed OIDs.
<strong># mongo-objectid-predict cheatsheet
</strong>
## Basic usage (predict forward ObjectIds)
python2 mongo-objectid-predict 6985ac948cbf4900093753c2

## Predict older ObjectIds (eg: find admin created before user)
python2 mongo-objectid-predict --backward 6985ac948cbf4900093753c2

## Increase guessing range (counter offset)
python2 mongo-objectid-predict --counter-diff 100 6985ac948cbf4900093753c2

## Generate multiple ObjectIds per counter value
python2 mongo-objectid-predict --per-counter 3 6985ac948cbf4900093753c2

## Wide backward prediction (common IDOR case)
python2 mongo-objectid-predict --backward --counter-diff 200 6985ac948cbf4900093753c2

## Generate many ObjectIds and save to file
python2 mongo-objectid-predict --counter-diff 1000 6985ac948cbf4900093753c2 > objectids.txt

## Stealthy low-noise prediction
python2 mongo-objectid-predict --backward --counter-diff 50 --per-counter 1 6985ac948cbf4900093753c2

## Fuzz predicted ObjectIds against API
ffuf -w objectids.txt -u https://target/api/user/FUZZ

Hashed Parameter

Sometimes we see websites using hashed values to generate a random user id or token, like sha1(username), md5(email), ...

  • MD5: 098f6bcd4621d373cade4e832627b4f6
  • SHA1: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
  • SHA2: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

Wildcard Parameter

Send a wildcard (*, %, ., _) instead of an ID, some backend might respond with the data of all the users.

  • GET /api/users/* HTTP/1.1
  • GET /api/users/% HTTP/1.1
  • GET /api/users/_ HTTP/1.1
  • GET /api/users/. HTTP/1.1

IDOR Tips

  • Change the HTTP request: POST → PUT
  • Change the content type: XML → JSON
  • Transform numerical values to arrays: {"id":19} → {"id":[19]}
  • Use Parameter Pollution: user_id=hacker_id&user_id=victim_id