The none Algorithm: Forging a JWT a Server Accepts Without a Signature

Web & API Security Level 3/4 ~5 min 2026-07-10

The challenge

This API authenticates you from the claims inside your JWT. The header says alg:HS256, but the server has a classic flaw: it also accepts a token whose header says alg:none, treating it as already valid with no signature to check. In the workbench, switch the header algorithm to none and rewrite the payload so role becomes admin. The token rebuilds live as you type. Copy the whole forged token and submit it.

What you'll learn

  • Understand what the JWT header alg field controls
  • Explain why honouring alg:none disables signature verification
  • Forge an admin token by switching the algorithm to none and editing the payload
  • Recognise alg:none acceptance as a critical authentication bypass
  • Know that a server must pin the expected algorithm rather than trust the token's header

Skills tested

JWT tamperingAuthentication bypassToken header manipulationPrivilege escalation

Prerequisites

  • A JWT is three base64url parts: header, payload, signature
  • Claims like role and user live in the payload
  • Basic JSON editing

How it works

A JSON Web Token carries an algorithm name in its header, for example {"alg":"HS256","typ":"JWT"}. The intent is that the server reads alg, then verifies the signature with that algorithm and a secret key. The fatal mistake some implementations make is to trust the attacker-controlled header to choose the algorithm. If the header says alg:none and the library honours it, the server treats the token as legitimately unsigned and performs no verification at all.

That turns the JWT into a plain, editable list of claims. Because nothing checks the signature, you can rewrite any claim you like. Here the access decision is the role claim, so you switch the header to {"alg":"none","typ":"JWT"} and change "role":"user" to "role":"admin". The workbench re-encodes both segments and rebuilds the token. The third (signature) segment no longer matters; an alg:none token is commonly sent with an empty signature, which is why a trailing dot with nothing after it is also accepted.

The whole class of bug exists because the algorithm should be a server-side decision, never something the caller can downgrade. Pin it.

Common mistakes

  • Only editing the payload. If you leave the header as HS256, the original signature is now wrong - this attack needs the header switched to none so the server skips the check.
  • Trying to compute a real signature. The point of alg:none is that you do not need one; do not waste time forging a valid HMAC.
  • Changing the wrong claim. Access here is decided by role; set it to admin, not user or sub.
  • Submitting the decoded JSON. Submit the rebuilt, re-encoded token (or its admin payload segment), not the human-readable claims.

How to defend against it

Never let the token's own header decide whether or how to verify it. The server must choose the algorithm and reject anything that disables verification.

  • Pin the expected algorithm server-side and reject alg:none (and any unexpected alg) outright before processing claims.
  • Use a vetted library version and pass the algorithm explicitly to the verify call; never rely on the library's default to read alg from the token.
  • Derive authorization only from claims on a token whose signature has been verified with the correct key.
  • Prefer short-lived tokens and, for sensitive roles, server-side session checks so one forged token is not total compromise.

Full solution

Pro and Max members unlock the complete step-by-step walkthrough.

Go Pro

Community stats

75 completions
82% success rate
M2F14M3 First blood

Related Daily Hacks

18,000+ Hackers 100+ Labs & Courses Free
Start Hacking Free