Skip to content
Security
Skill

/hunt-idor

IDOR / BOLA hunting - two-account methodology, identifier discovery and UUID leak chaining, the trusted-identifier test, GraphQL node and nested-object IDOR, cross-tenant escalation, write and delete operations. Bounded ID sampling, never range sweeps. Wiki-first, FIND schema

BOOST
From plugin
torch
33356 skills
Install
$ npx -y skills add Encod3d-Sec/TORCH --skill hunt-idor --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/hunt-idor

Context preview

The summary Claude sees to decide when to auto-load this skill.

IDOR / BOLA hunting - two-account methodology, identifier discovery and UUID leak chaining, the trusted-identifier test, GraphQL node and nested-object IDOR, cross-tenant escalation, write and delete operations. Bounded ID sampling, never range sweeps. Wiki-first, FIND schema

SKILL.md

hunt-idor.SKILL.md
name: hunt-idor
description: >
  IDOR / BOLA hunting - two-account methodology, identifier discovery and UUID leak chaining,
  the trusted-identifier test, GraphQL node and nested-object IDOR, cross-tenant escalation,
  write and delete operations. Bounded ID sampling, never range sweeps. Wiki-first, FIND schema
  output. Trigger on IDOR, BOLA, broken access control, object level authorization, cross-tenant,
  "read another user's data", "swap the id", or any API path or parameter carrying a numeric ID,
  UUID, or account identifier.

Hunt: IDOR / Broken Object Level Authorization

**Assumes `hunt-core`** for the scope gate, two-account rule, confirmation gate, enumeration limits, stop conditions, wiki protocol, FIND output, and Deadends. Do not re-derive any of that here.

Wiki

qmd_query "IDOR BOLA insecure direct object reference access control" via wiki-search MCP

Hub: [[web-moc]] (live web index). Primary page: [[access-control]]. Payload arsenal: `wiki/payloads/idor.md`. Anchors: [[uuid-insecurities]] (v1-UUID timestamp/MAC when an object ID is a UUID rather than a sequential integer), [[jwt-attacks]] (chain a trusted `sub`/`user_id` claim to ATO, hand off to hunt-auth).

Attack surface signals

URL patterns: `/api/v1/users/{id}`, `/invoices?id=`, `/reports/{uuid}/`, `/messages/{thread_id}`, `/admin/orgs/{org_id}/members`

GraphQL: any query or mutation taking an `id` argument. Check for `node(id: "...")` global lookups - one endpoint reaching every object type, with per-type authorization frequently missing on at least one.

**Rank before testing.** Not all endpoints are equally likely:

  • **Newest features** - middleware follows codebase conventions; a feature written outside them

misses it.

  • **Bulk and export endpoints** - one request, many objects, much higher severity per finding.
  • **Anything carrying two identifiers** - see the trusted-identifier test below.
  • **Cross-service internal calls** - the internal hop often carries no user context at all.
  • **File and document access** - frequently a separate host or CDN with no authorization beyond

knowing the ID.

  • **Non-GET verbs on read-looking endpoints** - `GET /orders/123` authorized, `PATCH` not.

Where the identifiers are

Check all of these; the least obvious are the least protected. Path segments, query parameters, request bodies (including nested objects), headers (`X-User-Id`, `X-Account-Id`, `X-Tenant-Id`), cookies, JWT claims, GraphQL variables, WebSocket messages, and file/CDN URLs.

**Get B's identifiers from B.** Log in as B and read them from B's own traffic, profile page, or JWT. Record in `identities.md`. Never obtain an identifier by incrementing until you find out whose it is - that is enumerating real users.

**Decode opaque identifiers before assuming they are random.** Base64 and hex frequently decode to a plain integer or a `type:id` pair. Where the ID is a hash, test whether it hashes something knowable (email, user ID, timestamp) and compute B's offline.

UUID: a two-part finding

A random UUID is not an authorization control, but it is a practical barrier. The finding becomes a chain:

1. **The check is missing** - test with B's UUID, which you legitimately hold. 2. **The UUID is obtainable** - find where it leaks.

Report both together. Part 1 alone gets triaged down as "requires an unguessable identifier."

Leak sources worth working: search and autocomplete endpoints, notification and activity feeds, team and member lists, verbose errors, notification emails, exported files, share and invite links, and objects you *can* read that reference objects you cannot.

Also verify the UUID is actually random - v1 encodes timestamp and MAC ([[uuid-insecurities]]), and hand-rolled implementations frequently emit sequential values dressed as UUIDs.

Methodology

**Setup:** two accounts per `hunt-core`. A owns, B attacks. Separate profiles.

**Drive it through Burp** for operator visibility. With A's request captured in Repeater or proxy history:

scripts/burp/idor-sweep.py <eng> <reqfile> --attacker-auth "Cookie: session=USER_B" --range 5

Sends owner-baseline / idor-test / bounded id sample through `send_http1_request`, diffs status and body, prints a verdict and a ready `capture.sh burp` PoC line. Honors `no_bruteforce` -> range 0. **Do not raise `--range` above the `hunt-core` limits without operator approval.**

For GUI-visible replay: `create_repeater_tab` for an A tab and a B tab, or `send_to_intruder` with a bounded number payload.

1. **Log in as A, browse every feature, note every ID** - object, UUID, org, invoice, thread. 2. **Baseline both directions.** A requests A's object. B requests B's object. Record status, length, body shape. You are testing against these, not against intuition. 3. **Cross-request:** B requests A's object with B's session.

# Baseline - A owns it
curl -s -H "Cookie: session=USER_A" https://target.com/api/v1/invoices/12345

# Cross-account - B attempts
curl -s -H "Cookie: session=USER_B" https://target.com/api/v1/invoices/12345

4. **Rule out legitimate access before claiming anything.** Is the object shared with B, in a shared team, public, or org-visible? Check the UI as B. This is the single most common false positive in this class - an app with sharing features generates them constantly. 5. **Trusted-identifier test - run this on every endpoint carrying two identifiers.** The highest value test in IDOR and the most frequently skipped. Make the session and the parameter disagree:

Session: account B
Body:    {"user_id": "<A's id>", "action": "..."}
  • Server acts on B -> identity derived from session, parameter ignored. Correct.
  • Server acts on A -> **the parameter is trusted.** IDOR, usually critical, fully

attacker-controlled.

  • Server errors on mismatch -> it compares them. Correct, and evasion is the next step.

Apply the same to JWT claims: modify `sub` / `user_id` and see whether the s

Read more
Ships withtorch

An AI-powered penetration testing and bug-bounty knowledge base and automation harness for Claude Code.

Get the whole plugin

Other skills on torch.

hunt-burp
Skill

hunt-burp

Drive Burp Suite over its MCP server as an AI triage + attack layer - review proxy history for signals, replay via Repeater/send,…

hunt-ad
Skill

hunt-ad

Active Directory attack hunting - enumeration to domain dominance. Spray-safe (lockout gate), AS-REP/Kerberoast, ACL + ADCS…

hunt-api
Skill

hunt-api

API attack hunting (REST / GraphQL / gRPC) - BOLA/IDOR, BFLA, mass assignment, excessive data exposure, auth/JWT, introspection +…