Overview
The application exposed its JWT signing key inside client-side TypeScript source code. By reading the key from the browser inspector and forging an admin token, we gained access to a privileged API endpoint and retrieved the flag.
- Vulnerability: Hardcoded JWT secret in the client-side bundle.
- Impact: Full authentication bypass / privilege escalation to admin.
Steps
1. Initial Recon, HTTPS Redirect

The app redirected HTTP traffic to HTTPS. Switched to the correct URL to reach the landing page.
2. Register & Enumerate

Created an account and logged in. Nothing sensitive was visible on the UI after scrolling through the app.
Intercepted traffic with Burp Suite, which revealed:
| Finding | Value |
|---|---|
| Endpoint | /api/tickets |
| Auth method | JWT (Bearer token + Cookie) |
The app was issuing JWT tokens and validating them on API requests, a good target for token forgery.
3. Source Code Review, Client-Side Secret Leak
Opened DevTools → Inspector and browsed the source tree. Found Page.tsx, which imported a generateToken function from @/lib/jwt.

Navigating to jwt.ts in the source revealed the JWT signing key hardcoded in plaintext, fully readable in the client-side bundle with no authentication required.

Root cause: The signing secret was committed into frontend source code and shipped to the browser, giving any user the ability to forge valid tokens.
4. Forge an Admin JWT
Using the leaked signing key, crafted a forged JWT with elevated privileges (e.g. role: admin). Since we know the secret, the server accepts our token as legitimate.

5. Inject Token & Capture the Flag
Replaced the original JWT in both auth locations on the GET /api/tickets request:

Cookie: authToken=<forged_token>
Authorization: Bearer <forged_token>
The server validated the signature, elevated the session to admin, and returned the flag in the response.

Flag
HTB{...}
Key Takeaways
- Never store secrets in client-side code. JWT signing keys, API keys, and credentials must live server-side only. Anything shipped to the browser is public.
- Source maps and bundled JS are readable. Even minified/compiled frontend code can be inspected in DevTools, treat it as untrusted territory.
- JWT forgery is trivial once the secret is known. A leaked signing key completely undermines the token-based auth model.