Authorize (access control)
Find broken access control by replaying captured flows across identities and mutations — prove an IDOR or privilege escalation by showing one user's request returning another user's data. Pro.
Authorize is Hugin's broken-access-control (BAC) engine. It finds the bugs where a request works for someone it shouldn't: IDOR, privilege escalation, cross-tenant access, and missing function-level authorization. You hand it a set of identities and a set of captured flows; it replays every flow as every identity, mutates the ids, roles, verbs, and scopes, and compares the responses. A finding is proof, not a guess — user A's request returning user B's data, baseline and replay side by side. Authorize is Pro.

Two halves
Passive signals are raised for free as you browse. A role or tenant field in a response body, a predictable id, an endpoint that answers the same with or without auth, a response shape that converges across users, a header that flips a decision, a request field echoed back, a SAML assertion worth a manual look. They do not prove a bug — they mark where to point the active audit, so the scan is corpus-driven rather than blindly exhaustive.
Active audit is the core. You define identity profiles, then Hugin replays captured flows across them and across mutations and reads the responses against your rules. This is the half that produces findings.
Define your identities
An identity profile is the credential set Hugin replays as: its cookies, headers, and bearer token, plus an expected role — admin, user, guest, anonymous, or custom. Mark one profile as the baseline; it is the anchor every replay is compared against. Add an anonymous profile that strips auth entirely — it is the fastest way to catch an endpoint that answers anyone. Each profile can carry a host scope so one vault rides across several targets without firing every identity at every host.
The matrix is only as honest as its sessions. Bind a login macro to each identity so its token refreshes automatically mid-run — see Macros and session rules. After 2 consecutive 401/403 or redirect-to-login responses an identity is marked stale and skipped, so a long run keeps firing the live identities instead of testing the login wall with a dead one.
The check catalog
Each check toggles independently, so you can run the whole catalog or isolate one
class. By default a check only fires on flows that fit it (JWT escalation on JWT
flows, OAuth scope on /token, GraphQL on GraphQL endpoints); flip force-enable
all when you know the target supports a scheme the captured traffic hasn't shown
yet.
Swap an id in the path (/users/123 → a peer's id). A 2xx means you read a resource
that isn't yours.
The same swap in a ?id= query or a body field, for endpoints that key the object
off the parameter instead of the path.
Replay the same URL as two different users and get identical data back — the classic
/api/Users/:id leak that id-mutation checks miss because no id changed.
Rotate a tenant or org id and land on another tenant's data. The boundary crossed is the organization, not the user.
Rotate every id Hugin collected while you browsed across every identity, so stored resource references get tried against users who shouldn't see them.
Replay a privileged request unchanged as a strictly-lower-privilege identity. A 2xx means a low-priv role reached an admin function — the role boundary failed, not the resource one.
A trusted-proxy header (X-Forwarded-For, X-Original-URL, and friends) flips a
401/403 into a 2xx — the app trusts a header an attacker controls.
The same URL answered with an alternate verb when the authz middleware only guards the captured method, leaving the alternate-verb handler exposed.
Swap a client-supplied role value (role=user → role=admin, is_admin=false →
true) and get a different 2xx — the server trusts the privilege you state.
Inject a privileged field the request never carried (isAdmin, role,
permissions, isVerified) and watch the server accept or echo it.
Tamper a JWT claim or scope and have it honoured without re-auth — a signature or verification flaw in the token path.
The authorization server hands back a token with the elevated scope you asked for
rather than the one the client is registered for. No forgery — it just trusts the
parameter.
Re-send a JSON body as XML or form-urlencoded and get the same result, bypassing authz rules that are enforced per request shape.
The anonymous replay returns the same protected data the authenticated baseline did — the endpoint has no auth check at all.
A captured 429 clears to 2xx when the token changes — the limiter is keyed to the session, so rotating tokens defeats it.
On GraphQL endpoints, mine the schema by introspection and probe sensitive or admin-only fields across identities.
Telling a real block from a decoy
A 200 is not always a leak and a 403 is not always a block. Hugin already reads the denial: 401 (not authenticated) versus 403 (authenticated but forbidden) versus a 404 that masks a resource another identity got a 200 for, versus a 3xx to a login page. On top of that, enforcement rules let you pin what a block and a bypass look like on this specific target. Each rule matches on a status code, a header, a body-contains string, a body regex, or a body length, then declares the response enforced or bypassed. That turns "is this 200 a leak or a soft error page?" into a deterministic verdict per target instead of a judgement call per flow.
To stop dynamic noise from breaking the body comparison, add ignore patterns that mask CSRF tokens, nonces, timestamps, and request-ids before Hugin diffs two responses.
Running an audit
Load your identities
Add a profile per identity with its cookies, headers, or bearer token; set the expected role; mark the baseline; add an anonymous profile. Bind a login macro to each so the matrix doesn't die on an expired session.
Pick the flows
Select flows from History, or leave the set empty to audit every in-scope flow in the project. Endpointer-seeded flows are already in the corpus, tagged and ready.
Choose the checks
Toggle the catalog above to taste. Set per-target enforcement rules and, if needed, endpoint-specific similarity thresholds.
Set the budget and pace
Cap the run with a request budget (5,000 by default) and a per-probe delay to stay under rate limits. The body-similarity threshold defaults to 0.9; tighten it if a target's responses are noisy.
Pick the comparison mode
Pairwise compares the baseline against each identity — the cheap default. Full matrix compares every ordered pair, for an N-way admin × manager × user × anonymous audit. Then run it.
You can replay through Hugin's proxy so the audit's own traffic lands in History under your scope and rules. Watch the run with the live progress counters, and cancel a run that's drifting wider than you intended.
Reading a finding
Every finding shows the baseline and the replay flow side by side — the Original,
Replayed, and Diff panes — with a one-line evidence string such as
200 as user-b vs 403 as anonymous, body 4129 == 4129 bytes, so the proof is in the
finding, not in your memory of the run.
Each IDOR-class finding is tagged horizontal or vertical. Horizontal is peer-to-peer access of a same-role resource (path-param IDOR, cross-identity echo, cross-tenant). Vertical is privilege escalation (header bypass, JWT, role, OAuth, auth-optional leak, verb tampering, content-type polyglot). Generic query/body parameter mutation is left undetermined for you to label.
Severity follows the bug. The hard access-control breaks — header bypass, cross-tenant, mass assignment, JWT, path-param IDOR, OAuth scope, verb tampering, BFLA — land Critical. Cross-identity echo, parameter IDOR, auth-optional leak, and rate-limit bypass land High. Status divergence, role escalation, and content-type polyglot are Critical when the replay body matches the baseline (same data leaked) and High otherwise. Confirmed findings flow to Findings for triage.
From Endpointer to Authorize to YesWeHack
Endpointer is the input side: it probes which endpoints enforce auth and seeds the gated ones — with Nerve parameter signals — into the BAC corpus. Authorize is where the cross-identity replay runs against that corpus. When a finding holds up, hand it to YesWeHack; Authorize pre-selects the bug type from the finding's class (IDOR findings map to CWE-639, the rest to the access-control buckets) so you're not re-deriving the CWE by hand.
Mutations can synthesize destructive verbs (PUT/PATCH/DELETE) that persist writes against the target. That is off by default — verb tampering only retries a safe POST until you opt in. Turn it on only for an engagement you're authorized to break, and keep the whole audit inside scope.