JSON Web Tokens are everywhere: APIs, user sessions, SSO. And when servers implement them poorly, they become a direct backdoor into privileged accounts.
In this walkthrough, we'll solve the "JWT authentication bypass via unverified signature" lab from PortSwigger Web Security Academy using HackUtils — a 100% client-side tool that runs entirely in your browser without sending your tokens to any external server.
What vulnerability are we exploiting?
Some servers decode JWTs to read claims (like sub or role), but never verify that the signature is valid. This means you can freely modify the payload — change your username to administrator, for example — and the server will accept it without question.
It's one of the simplest and most critical JWT vulnerabilities that exist.
Setup: The Lab
We activate the lab on PortSwigger. Objective: access the /admin panel and delete the user carlos.
Link: https://portswigger.net/web-security/jwt/lab-jwt-authentication-bypass-via-unverified-signature

Credentials provided by the lab: wiener:peter. A regular user with no admin privileges.
Step 1: Login and JWT Interception
We navigate to /login, enter the credentials, and leave Burp with Intercept on.

After a successful login, the server redirects us to /my-account and we are authenticated as wiener.

Now we look at the POST /login response in Burp. In the Set-Cookie header we find the session JWT:

We copy that token. It contains all the session information, signed (or supposedly signed) by the server.
Step 2: Decode the JWT in HackUtils
We open hackutils.com, go to the JWT Decoder section, and paste the token.

At a glance we can already see the most important details:
- SUBJECT (SUB):
wiener— our current user - EXPIRATION (EXP): human-readable date, no need to manually convert the epoch timestamp
- ISSUER (ISS):
portswigger
Scrolling down we see the full Header and Payload:

We can see:
// Header
{
"kid": "2ab73edc-4a61-4b5c-a9ae-e46514d5880f",
"alg": "RS256"
}
// Payload
{
"iss": "portswigger",
"exp": 1772177891,
"sub": "wiener"
}The algorithm is RS256 (asymmetric RSA). Under normal conditions, modifying the payload would invalidate the signature because we don't have the private key. But remember: this server never verifies the signature. It doesn't matter what's in it.
Step 3: Modify the sub Claim
The Header and Payload panels in HackUtils are directly editable — no copying, no pasting into a separate editor.
We click on the "sub" field in the Payload and change it:
"sub": "wiener" → "sub": "administrator"
Now we click Rebuild & Verify. HackUtils reconstructs the token with the modified payload. The signature in the third part of the JWT will be outdated — but that doesn't matter because the server doesn't validate it.

We copy the modified token.
Step 4: Replace the Token and Access /admin
Back in Burp, we try to access /admin with our original token. The server blocks access:

We intercept the GET /admin request in Burp and replace the session cookie value with our modified token.

We forward the request. The server reads the claim "sub": "administrator", skips signature verification, and grants us access to the admin panel.
Step 5: Delete carlos
Inside the admin panel we see the user list: wiener and carlos. We click Delete next to carlos.

The request goes through with our forged admin token. The server accepts it.
Lab Solved ✅

Why HackUtils instead of jwt.io?
When you're on a real engagement, the JWT you intercept may contain sensitive production data: real user IDs, roles, session data. Pasting it into jwt.io means sending it to a third-party server.
HackUtils processes everything in your browser. The token never leaves your machine. For a professional pentester, that's not a minor detail.
Beyond privacy, HackUtils also offers things jwt.io doesn't:
- Automatically converts
iat/exptimestamps to human-readable dates - Built-in alg:none attack with all bypass variants ready to copy
- Header and Payload are editable directly in the same interface
- No account or registration required — just open and use
Conclusion
This vulnerability is a reminder that signing a JWT is not enough — the server must verify that signature on every single request. If it doesn't, the token is about as secure as plain text.
The lab is rated Apprentice for a reason: the exploit is trivial. Change a string in an editable field and copy the result. But in the real world, this kind of misconfiguration shows up in production applications more often than you'd expect.
Try HackUtils on your next engagement: hackutils.com
Written by @stuxboynet
Tags: Penetration Testing JWT Web Security PortSwigger Ethical Hacking Bug Bounty Red Team OSCP Hack Cybersecurity