Rainbow Rocket
Challenge Overview
We were provided with a website and the complete source code for both its frontend and backend. The objective was to retrieve the flag, which was accessible via a /flag endpoint if the correct authentication was provided.
Initial Analysis
- Explored the website manually and identified the API endpoints, especially
/flagthat will return the flag. - Reviewed the internal code structure and identified the use of JWT (JSON Web Tokens) for authentication.
- No SQLi was present as the backend used prepared statements for database queries.
Vulnerability Discovery
Upon inspecting the backend code, I discovered that JWT tokens were processed using jwt.decode instead of jwt.verify. This means the backend decoded the token payload without verifying its signature. The only check performed was whether the username field in the token payload was set to "admin":
const payload = jwt.decode(token);
if (payload.username === "admin") {
// return flag
}
This is insecure because anyone (like me for example ^^) can forge a token with an arbitrary payload, and the backend will accept it as long as the username is "admin".
Exploitation Steps
- Register a new user with any username.
- Log in to obtain a valid JWT token.
- Decode and modify the token:
- Use a tool like https://token.dev/ to decode your JWT.
- Change the
usernamefield in the payload to"admin". - Re-sign the token (the signature does not matter since the backend does not verify it).
- Send a request to
/flagwith the modified JWT token in theAuthorizationheader.
Example (using curl):
curl -H "Authorization: Bearer <forged_jwt_token>" https://thewebsite.fr/api/flag
Flag Retrieval
The backend accepted the forged token, recognized the username as "admin", and returned the flag in the response.