Skip to main content

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 /flag that 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

  1. Register a new user with any username.
  2. Log in to obtain a valid JWT token.
  3. Decode and modify the token:
    • Use a tool like https://token.dev/ to decode your JWT.
    • Change the username field in the payload to "admin".
    • Re-sign the token (the signature does not matter since the backend does not verify it).
  4. Send a request to /flag with the modified JWT token in the Authorization header.

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.