Access control testing
Prove BOLA, BFLA, IDOR, and privilege bugs by replaying requests across identities, with an ID corpus and headless audits. (Pro)
This is the engine behind Authorize and Endpointer: the broken-access-control (BAC) bug families they prove, the identifier corpus that drives IDOR, and how to run an audit headless. It's Pro.
How Hugin proves an access-control bug
Hugin replays a request that worked for one identity as another — your admin profile, user A, user B, or no credential — then diffs the responses. That cross-identity comparison is the authorization matrix: when a low-privilege identity gets the same 200 and the same body as the owner, the server never checked who was asking. Each finding pairs the baseline and replay flows, scores severity and confidence, and marks the break horizontal (another user's data) or vertical (a privilege you shouldn't hold).
Passive signals you raise while browsing — predictable IDs, role and tenant fields, identity drift, shape convergence, header flips, mass-assignment echoes, and SAML assertions — mark where to aim; the active audit confirms it.
What it detects
IDOR via a path, query, or body parameter, plus cross-tenant access — rotate a tenant or org id and land on another customer's resource.
An admin-only route reachable by a strictly lower-privilege identity — the boundary crossed is the role, not the resource id.
Flip a client-supplied role field (role=user → admin, is_admin), mass-assign
a privileged field on a write, forge a JWT (strip the signature with alg:none,
swap claims, crack a weak secret), or elevate the OAuth scope a /token request
returns.
Method tampering (swap GET for PUT/DELETE), Content-Type polyglots,
header-based authorization bypass, and rate-limit bypass keyed to the session token
instead of the IP.
The ID corpus that drives IDOR
Browsing harvests the identifiers out of responses, each classified as numeric, UUID v1, UUID v4, UUID v7, other UUID, slug, hex, or opaque token. The predictable kinds — numeric, UUID v1, and UUID v7 — are flagged worth attacking first: a v7 UUID embeds a millisecond timestamp, so IDs minted together share a long common prefix you can walk. The IDOR checks enumerate against this corpus, not random guesses.
Seed the corpus from an API spec
Import an OpenAPI v2/v3 or Swagger JSON; Hugin walks every path, pulls the example IDs, and classifies them into the corpus — so an audit enumerates the spec's own identifiers before you have browsed a page.
Run it headless or from an agent
The pipeline runs without the GUI. The bac_audit MCP tool drives a run: start an
audit, poll progress, cancel, list findings / signals / corpus,
seed_corpus from a spec, to_ratrace to pivot a confirmed finding into a
race-condition probe in RatRace, set triage
status, and export. The hugin bac command mirrors the read side for scripts and
continuous integration (CI):
hugin bac findings --severity high
hugin bac corpus --kind numeric
hugin bac export --format sarif > bac.sarif
Export for reports and CI
export writes findings as SARIF, Markdown, HTML, CSV, or a JSON summary. SARIF
drops into a code-scanning dashboard or CI gate; Markdown and HTML go into the
client report.
An audit only runs against what you feed it — the identity profiles from Authorize and the gated endpoints Endpointer seeds. Profile first, then run the matrix.