Tamper the Token: Forging a JWT When the Signature Is Not Checked
O desafio
Este painel decide o que você pode ver a partir da claim role dentro do seu JWT - e ele nunca verifica a assinatura, então a claim é sua para mudar. Na bancada, edite o payload para que role vire admin. O token se reconstrói ao vivo. Copie o token forjado inteiro (as três partes, com os pontos) e envie.
O que você vai aprender
- Understand that a JWT signature only protects claims if the server verifies it
- Tamper a payload claim and observe the token re-encode in real time
- Forge a privilege-escalated token by changing the role claim to admin
- Recognise signature-verification gaps (skipped checks, alg:none) as critical auth flaws
Habilidades testadas
Pré-requisitos
- Awareness that JWTs carry claims like role and user id
- Basic JSON editing
Como funciona
A JSON Web Token splits into three base64url parts: header, payload, and signature. The signature is the only thing that makes the payload trustworthy - it is a keyed hash over the header and payload, so if anyone edits a claim, the signature no longer matches and a correct server rejects the token. Take that check away and the JWT becomes what it physically is: a plain, editable list of claims with a useless string stapled on the end.
That is the flaw here. The dashboard reads role straight from the payload to decide access, but it never verifies the signature (a common real bug, alongside accepting alg:none). So you can simply rewrite the claim. In the workbench you decode the payload, change "role":"guest" to "role":"admin", and the tool re-encodes the payload and rebuilds the token live. The original signature - now mathematically wrong - is carried along unchanged, and because the server does not check it, your forged token authenticates you as an administrator.
The point of the exercise is the act of forging, not reading. Decoding alone tells you nothing an honest token would not; the vulnerability only appears when you change a claim and the server still trusts it.
Erros comuns
- Only reading the payload. Decoding is free and proves nothing - the bug is that you can change a claim and still be trusted.
- Editing the wrong field. The access decision is the
roleclaim; change its value toadmin, not the user or sub. - Submitting the decoded JSON. The answer is the rebuilt, re-encoded token (or its payload segment), not the human-readable claims you typed.
- Trying to fix the signature. You do not need a valid signature here - the whole point is that the server never checks it.
Como se proteger
The fix is non-negotiable: always verify the signature with the expected algorithm and key before trusting a single claim, and reject alg:none outright. Never make an authorization decision on an unverified token.
- Verify the JWT signature on every request, pinning the algorithm server-side (no
none, no client-chosen alg). - Derive authorization from verified claims only, and prefer short-lived tokens.
- Consider server-side sessions or token revocation for sensitive roles so a single forged or stolen token is not game over.