Burp Suite extension · access control
Manual pentesting in the AI era
needs an upgrade.
No more four browser windows. No more swapping sessions by hand to check who can read what.
Browse as each of your accounts and Penjester replays everything you did as everyone else, then proves what came back that should not have. It runs inside Burp Suite, opens to your own local AI model over MCP, and no model ever sends a request.
A personal tool, built to speed up manual access-control testing and do in one workbench what otherwise takes a stack of single-purpose extensions.
What it prints
The output is a board, so this page is one too
The problem
Authorization is the bug class every tool skips
SQL injection and XSS have good scanners, because a payload either reflects or
it does not, and one session is enough to tell. Authorization is different. To
know that /invoices/4471 is alice's and that bob should not have
it, a tool needs bob's session, alice's session, and some notion of who owns
what.
That is the entire gap. It is also why broken access control sits at the top of the OWASP Top 10 and still gets found by hand, one identifier at a time, by somebody with four browser containers open.
owner alice 200 59,534 bytes
actor bob 200 57,021 bytes
93% alike, 4% apart, so a scanner stops here and
calls it a finding.
owner-identifying values returned 0 of 20
so it is not one. bob got its own page.
Method
Six steps, and none of them guess
Whose session was that
Browse normally, as each account. Penjester attributes every request to the session that carried it, including when two accounts use cookies with different names, which is the usual case.
As everybody else
Every recorded request goes out again as every other account, with the whole credential set exchanged: cookies, auth headers, body tokens, and all three anti-forgery carriers.
A 200 is not a finding
Penjester sends an identifier belonging to nobody, repeats the request, and strips every credential, then asks whether the account was already entitled to the object before any of this ran.
Say what was skipped
Every refusal, skip and guardrail is recorded with its reason. A findings list that does not say what was never reached reads as an all-clear, and an all-clear nobody earned is the most expensive thing a security tool produces.
Could you have known the id
An IDOR on a UUID nobody can obtain is not a finding. Penjester searches every response your account genuinely received for that identifier and records how many it read. A searched silence, not an assumed one.
With the request behind it
Findings arrive in Repeater with the numbers that settled them. Right-click any row to reproduce it by hand, swap an identifier, or send it as somebody else.
Evidence
A finding that cites its own numbers
“Similar in shape and length” is the sentence that gets a report sent back. Penjester carries every number it measured all the way to the write-up: the size gap, the threshold it was weighed against, where that threshold came from, and how many of the owner's identifying values came back out of how many existed.
The noise floor is learned per endpoint from its own repeated reads, so an endpoint that swings 19 % between two identical requests is not judged by the same bar as one that is byte-stable. Shape is never decisive on its own. That rule is a line of code, not a guideline.
What settles it
owner-identifying values returned 3 of 20
present in alice's reply, absent from bob's own
Measurements
body similarity 93%
size gap 4%, against 19% measured from
this endpoint's own repeat reads
this reply 57,021 bytes, owner's 59,534
Probes
✓ nonexistent identifier → 404
✓ repeated → identical
✓ no credentials → 401
In Burp
One extension, not a drawer of them
Penjester is a Burp extension, not a separate console. Your proxy, your browser, your Repeater, your project file. One workbench in place of a stack of extensions.
What it will not do
The limits are the product
Most of what makes Penjester trustworthy is what it refuses to do. These are not roadmap items, and none of them is a setting.
- — No model composes a request A language model chooses which feature to look at and which result to write up. It never builds a request, never picks a payload, never gets a shell. One function sends everything, and it is not reachable from a prompt.
- — Nothing runs on its own A run starts because somebody typed the command. There is no daemon, no schedule, and no “it was already scanning when I opened it”.
- — No credential reaches a prompt The model is told cookie names. It is never handed a value, and the tool API has no shape that could return one.
- — No payload scanner SQLi and XSS already have good tools. Access control does not. Penjester stays on the ground nothing else covers, and points Burp's own Scanner at the rest when you ask it to.
- — No severity score Severity is demonstrated impact, and only somebody who knows what the data is can say it. Penjester suggests a starting point and never a number.
Get started
It is one jar.
Build it, point Burp at it, save two sessions, and browse. The first cross-account result usually arrives before you have finished logging in as the second account.