TL;DR: The app verifies JWTs with Authlib 1.6.6, which accepts
alg: none. Forge an unsigned admin token and bypass authentication entirely.
The alg: none attack exploits libraries that trust the algorithm declared in the JWT header without enforcing a strict allowlist. A token with alg: none carries no signature - anyone can write any payload.
- Stack: Python + Flask + Authlib 1.6.6
- Class: alg:none bypass
docker build -t lab2 .
docker run -p 3000:3000 lab2Without Docker:
python -m venv .venv && . .venv/bin/activate # or .venv\Scripts\activate on Windows
pip install -r requirements.txt
python app.pyOpen http://localhost:3000.
- Login as any user (not
admin) to observe the token format - Forge a JWT with
alg: noneandrole: adminin the payload - Leave the signature empty (trailing dot:
header.payload.) - Replace your
sessioncookie with the forged token - Call
GET /api/admin/data - Capture the flag
- JWT parts are Base64URL-encoded - you only need
base64and a text editor - The trailing dot is required:
header.payload.- no signature, but the dot must be there - No login needed; the server never checks if the token was issued by itself
pip install requests pwntools
python poc.py
# or: python poc.py --url http://localhost:3000Full walkthrough: SOLUTION.md
- Critical vulnerabilities in JSON Web Token libraries - Auth0 - The original 2015 disclosure naming the alg:none attack and why mixed-case variants (e.g. "NoNe") bypass naive checks
- JWT none algorithm supported - PortSwigger KB - Concise definition of the issue and detection guidance
- CVE-2022-23540 - NVD - jsonwebtoken <=8.5.1 accepting alg:none when a falsy secret is passed to jwt.verify()