SuperAPI AI Directory

idor-methodology

Security & auditing

View repository

Updated 10-16 09:50

About this skill

IDOR Insecure Direct Object Reference Methodology

IDOR is one of the most common API vulnerabilities—developers check "are you logged in" but not "are you authorized to access this data." Change one number and you can get someone else's data; change one role and you can become an administrator.

⛔ In-depth Reference


Phase 1: Discover IDOR Entry Points

Any location with an object identifier is an IDOR candidate:

Location Example Priority
URL Path /api/users/1001 🔴 High
Query Parameter ?user_id=1001&order_id=5003 🔴 High
POST/PUT Body {"user_id": 1001} 🔴 High
Cookie/Header uid=1001 / X-User-Id: 1001 🟡 Medium
File Path /uploads/user_1001/avatar.jpg 🟡 Medium
GraphQL Variable query { user(id: 1001) {...} } 🔴 High
WebSocket Message {"action":"getProfile","uid":1001} 🟡 Medium

Key identification signals: auto-incrementing integers, short serial numbers (ORD-001), Base64-encoded IDs, filenames/paths in URLs.

Phase 2: Horizontal Privilege Escalation Testing (Read Operations)

Requires at least two accounts (register two, or know your own ID).

账户 A (uid=1001) 的 Token:
GET /api/users/1001/profile → 200(自己的数据,记录作为基线)
GET /api/users/1002/profile → 200 + 不同数据?→ IDOR!
GET /api/users/1/profile    → 管理员数据?→ 垂直越权!
GET /api/users/0/profile    → 500 错误泄露内部信息?

Response comparison analysis(do not just look at the status code):

Response Judgment Next Step
200 + different user's data ✅ IDOR confirmed Save evidence, test write operations
200 + same data Backend ignored the ID parameter Try other endpoints
200 + empty data User does not exist or data is empty Try a different ID range
403/401 Has permission check Try bypass → Phase 5
404 ID does not exist Try a different ID range or enumerate
500 Backend error Analyze the error message

→ Batch detection scripts → references/idor-techniques.md

Phase 3: Write Operation Privilege Escalation

After confirming read privilege escalation, write operations are 10 times more harmful—being able to change a password means being able to take over an account:

PUT    /api/users/1002         {"email":"evil@x.com"}    → 接管账户
PATCH  /api/users/1002         {"password":"hacked"}     → 改密码
DELETE /api/orders/5003                                   → 删除他人订单
POST   /api/users/1/reset-pwd                             → 重置管理员密码
PUT    /api/users/1002/role    {"role":"admin"}           → 提权

Important: Many applications have permission checks on GET but forget them on POST/PUT/DELETE—all HTTP methods must be tested.

Phase 4: Vertical Privilege Escalation

Access administrative functionality using a regular user identity:

GET  /api/admin/users          → 管理员用户列表?
POST /api/admin/create-user    → 能创建用户?
GET  /api/admin/config         → 系统配置泄露?
GET  /api/internal/dashboard   → 内部面板?

Approval/Workflow System Privilege Escalation

In OA, contract approval, and ticketing systems, the "approval" operation is the most typical vertical privilege escalation target—call the administrator's approval endpoint using an employee identity:

# 例如
POST   /contracts/1/approve
PATCH  /contracts/1  {"status":"approved"}
POST   /api/admin/approval  {"id":1,"action":"approve"}

Key: Approval endpoints are often not standalone files, but embedded in the dashboard's $_POST['action'] In progress. If there is LFI/source code, search directly from the source code for approve/审批/action to find the exact endpoint; do not blindly guess the path.

JWT Claims Tampering: Decode the JWT → change "role":"user" to "role":"admin" → if alg:none or a weak key allows forgery

Mass Assignment: Inject during registration/update {"role":"admin","is_admin":true}

Phase 5: IDOR Bypass Techniques

When basic testing returns 403, do not give up—many permission checks can be bypassed:

Bypass Method Example
ID Parameter Wrapping id=1002 → id[]=1002、id={"$eq":1002}
HTTP Method Switching GET 403 → PUT/PATCH/DELETE 200?
Path Variants /api/v1/ → /api/v2/、/api/internal/
Encoding Bypass Base64, Hex, double URL encoding
Parameter Pollution HPP ?id=mine&id=victim(the backend may take the last one)
Content-Type Switching JSON→XML→form-urlencoded (different parsers have different filtering)
Request Smuggling/Chunking Bypass the frontend proxy's permission checks

→ Complete bypass payloads and scripts → references/idor-bypass-techniques.md

Phase 6: Multi-step IDOR Chains

Many IDORs are not single-step—you need to obtain information from endpoint A, then exploit it at endpoint B:

1. GET /api/comments → 评论中泄露 user_id: 1002
2. GET /api/users/1002/profile → 用泄露的 ID 读取个人资料
3. GET /api/users/1002/orders → 进一步读取订单数据

1. GET /api/invites?code=ABC → 响应含 group_id: 77
2. GET /api/groups/77/members → 用泄露的 group_id 获取成员列表

ID Leak Hunting Checklist: comments, messages, logs, invitation links, share links, exported files, API error responses, GraphQL Introspection, JS frontend code.

→ Detailed hunting workflow → references/idor-advanced-patterns.md

Phase 7: File/Media Resource IDOR

Uploaded files often lack permission checks even more than API data:

/uploads/user_1001/avatar.jpg   → 改 1001 为 1002
/attachments/report-001.pdf     → 遍历编号
/export/data-20260101.csv       → 改日期遍历
/media/a1b2c3d4.jpg             → 可预测哈希?

S3/OSS Direct Links: if the file URL is https://bucket.s3.amazonaws.com/users/1001/doc.pdf, directly changing the path may bypass application-layer permissions.

Phase 8: Batch Operations and Indirect References

Batch Operation IDOR

// 批量端点可能完全跳过单条权限检查
POST /api/users/bulk {"ids": [1001, 1002, 1003, 1004]}
POST /api/orders/export {"order_ids": [5001, 5002, 5003]}

// GraphQL batch
[
  {"query": "{ user(id:1) { email } }"},
  {"query": "{ user(id:2) { email } }"}
]

Indirect Reference IDOR

Instead of numeric IDs, use email/phone/username:

GET /api/users?email=victim@test.com     → 用邮箱查别人
POST /api/password-reset {"phone":"13800138001"}  → 用手机号重置
GET /api/profile/john_doe                → 用户名即标识符

→ Detailed patterns → references/idor-advanced-patterns.md

Phase 9: Framework-Specific IDOR

Different backend frameworks have different high-incidence IDOR patterns:

Framework High-Incidence Point Reason
Spring Data REST /{entity}/{id} fully exposed Auto-generated CRUD endpoints, no permissions by default
Django REST Framework /api/{model}/{pk}/ ViewSet is open by default; forgot to add permission_classes
Express + Mongoose /api/users/:id Incorrect middleware order causes authentication to be skipped
Laravel /api/{model}/{id} Route Model Binding automatically queries; forgot to add Policy
GraphQL (any) query { node(id:"...") } Relay Global ID may expose arbitrary objects

Evidence Collection Standards

A valid IDOR PoC must proveyou saw someone else's data, not your own:

  1. Request/Response Pair: complete HTTP request (including auth headers) + complete response
  2. Two-Account Comparison: Account A accesses Account B's data; Account B accesses the same endpoint to confirm the data belongs to B
  3. Key Field Annotation: highlight sensitive fields in the returned data (name, email, phone number)
  4. Prove ID Difference: clearly indicate that the ID in the request differs from the currently logged-in user's ID
✅ 好的证据:
"用 A 账号(uid=1001) 的 token 请求 /api/users/1002/profile,
返回了 B 账号的姓名(张三)、邮箱(zhangsan@test.com)、手机号"

❌ 差的证据:
"请求 /api/users/1002 返回了 200"
(没有证明返回的是别人的数据)

Each time an IDOR is confirmed, immediately evidence_save + report_vuln, including: request URL, request headers, response status code, and a summary of sensitive data in the response.

CTF Special: Flag Acquisition

Visit /api/flag, /admin/flag | Check admin profile/notes | Check user with ID=1 or high-privilege user | /api/users/0 or /api/users/-1