Lesson 2 of 3 in Broken Authentication · 2 min left in this chapter
Forge The Token
A real bank back office, a real login, and a session token you can rewrite by hand. You will forge a token that makes you the controller, set it, and open the vault an analyst was never meant to reach.
3 min read
Not yet reviewed
The lab for this chapter is the Ledger's back office. You have an analyst's login. But you are not going to log in as the controller — you are going to *write yourself* a controller's token.
Write it myself? Without the signing key?
Without any key. That is the point of alg: none. Watch what it costs you: three lines and a trailing dot.
Legal
This ledger is ours and is meant to be broken. Forging a session token to assume a role you were not granted, on a system you do not own or have written permission to test, is unauthorised access and a serious offence. The technique is legal to learn; using it without authorisation is not.
The forgery
A token is base64url(header) + "." + base64url(payload) + "." + signature. For an alg:none token, the signature is empty — so the token ends in a dot with nothing after it. You need the two JSON parts:
header {"alg":"none"}
payload {"sub":1,"role":"controller"}
- Line 1The header declares that this token needs no signature. The verifier honours it and skips the check entirely.
- Line 2
role: controlleris the claim that matters — the app reads your role from the token, not from the database.sub: 1names a real user so the account resolves; the role is the forgery.
Building and setting it
Base64url-encode each part, join them with dots, and add the trailing dot for the empty signature. In your browser's console on the lab tab, encoding is one function each:
const b = (o) => btoa(JSON.stringify(o)).replace(/\+/g,'-').replace(/\//g,'_').replace(/=+$/,'')
const t = b({alg:'none'}) + '.' + b({sub:1,role:'controller'}) + '.'
document.cookie = 'eq_ledger=' + t + '; path=/'
- Line 1base64url is base64 with two characters swapped and the padding removed — that is the whole difference.
- Line 3Set the forged token as your session cookie, then reload. The app now believes you are the controller, because its verifier believed the header.
Now do it
Forge the token, set the cookie, and open the Vault — the controller-only page an analyst has no link to. Inside is a controller reference. That reference is your flag, and it is unique to you. Submit the one your session shows.
You set sub: 1, which is an ordinary analyst. Why does that account get controller powers, when its real role in the database is not controller?
sub only decides which user record loads; the role claim beside it is taken as authoritative. The forged token says controller, and nothing re-checks that against the database — so the analyst account acts with a controller's rights for exactly as long as the token says so.What actually went wrong
Two mistakes stacked. The verifier accepted alg:none, so the signature — the only thing binding the token to the server — was optional. And the app trusted the role claim inside the token instead of re-reading it from the database. Either alone is dangerous; together they let an analyst write themselves a controller's session in three lines.