Hack the Box Critical Ops
- BlueDolphin
- 12 minutes ago
- 3 min read

Summary:
A vulnerable web app generated JSON Web Tokens (JWT's) on the client side. The signing secret and client-side generation logic were discoverable in the client JavasScript, allowing me to forge a valid token with elevated privileges and access the admin ticket board. This post shows how the issue was identified, exploited, and how to fix it properly.
Client-side JWT token attacks:
In normal circumstances the JWT's are signed by the server so endpoints can verify the token's integrity and trust claims (user id, role, expiry). Should the code be generated and signed client side, the user can create arbitrary valid tokens.
Why are Client-side JWT tokens used if they can be exploited?
Developer convenience / testing: Client side generation makes for much quick front end testing.
Misunderstanding: sometimes developers may think JWT's are just for transporting trust claims when in fact the signing must be secret before the transportation.
Poor separation: small project can sometimes rely on too much logic in the client to avoid backend infrastructure.
Third-party libraries or templates: examples or untrusted libraries sometimes have client side logic be default.
How to prevent them?
Generate and sign all JWT's server side only.
Never store signing secrets or private keys in client-side code or public repos.
Enforce server-side validation with well maintaned libraries.
Drop tokens with alg = none.
Rotate secrets and keep them in a secrets manager.
Walkthrough
1) Discovery - Where the token lived
Intercept traffic with Burp while logging in.
Note that there is no Set-Cookie.
Inspect the front end to identify the JWT generation client side function and comment "TODO: move signing to server"
Tip: In DevTools --> Sources search for JWT, sign, secret, Hs256 or the tokens name as defined by the app.

Client side cookie generation There is a script for generating JWT tokens client side, and a comment suggesting this needs to be server side only.

Burp Cookie Forging
Understanding that the JWT token is being generated client side, and having the JWT signing secret we can proceed to forge the request.

3) Forge a token
High-level steps (tools: jwt.io, Burp, or Burp JWT Editor plugin):
Clone the intercepted token.
Modify claims you want to escalate (e.g., role: "admin").
Sign it using the discovered secret with the same algorithm (HS256).
Replace the original token in the request (cookie or Authorization header) and replay.
Example payload (for demonstration only):
{
"sub": "42",
"username": "attacker",
"role": "admin",
"iat": 1699999999,
"exp": 1700003599
}
If the app accepts the forged token, you'll gain the privileges encoded in the token.
Burp workflow
Intercept login or a privileged request.
Right-click the request → Send to Repeater.
Replace cookie or Authorization: Bearer <token> with forged token.
Send and observe admin content or a 200 response.
Tooling tip: Burp has extensions (e.g., JWT editor) or use local jwt CLI (npm i -g jwt-cli) or python-jose to sign tokens quickly.
4) Why this worked in this case
Because the secret was in the client, signature verification on the server was still happening, but the attacker could produce a valid signature. The server implicitly trusted the token it received and used claims (role) to gate access.
Detection & monitoring suggestions
Add WAF rules / detection signatures for alg: none or tokens with suspicious claim values.
Alert on the app serving JavaScript files containing secret, JWT_SECRET, or long base64 strings.
Monitor for tokens being used from many IPs or sudden privilege escalation patterns.
Comments