Category: Web Vulnerability: Mass Assignment / Insecure Parameter Binding Hint Provided: "Improper Authorization has been fixed! I think we are ready for production!"
1.1 Initial Reconnaissance
The challenge presented a user registration and login portal with no immediately obvious attack surface. The key differentiator was the downloadable ZIP file containing the backend source code — app.py. In a real engagement, this is akin to having access to a .git directory or a leaked repository, and it's a massive advantage.


1.2 Vulnerability Identification (Static Code Analysis)
Focusing on the /api/register endpoint revealed the flaw:

record.update(incoming) overwrites the 'role' field if supplied by the attacker.The developer correctly initialized the record dictionary with a secure default role: 'standard'. However, the subsequent record.update(incoming) merges the entire user-supplied JSON object into the record dictionary. Because dict.update() overwrites existing keys without discrimination, an attacker can supply a "role": "admin" field in the registration request to escalate their privileges.
This is a classic Mass Assignment vulnerability. The application trusts the client to supply only expected fields, but fails to enforce an allow-list of permitted parameters.
1.3 Exploitation Path
- Register a new account, injecting the
roleparameter. - Log in with the newly created admin account.
- Access the
/adminpage, which checkssession.get('role') == 'admin'.
1.4 Step-by-Step Exploitation
Step 1: Register an Admin Account
Send a POST request to /api/register with a JSON payload that includes the "role": "admin" key-value pair.

The server responds with a redirect to the login page, confirming account creation.
Step 2: Log In
Use the credentials from Step 1 to authenticate via the login form. The session cookie now identifies the user as having the admin role.

Step 3: Retrieve the Flag
Navigate to /admin. The application verifies the session role and renders the admin dashboard, which contains the flag.


1.5 Key Takeaways
- Never use
dict.update()(or similar object merge functions) directly with untrusted input. Always explicitly extract only the expected fields. - Implement a strict allow-list for parameters that can be modified by the user. Libraries like Marshmallow or Pydantic make this straightforward.
- "Fixing" authorization on the frontend without addressing the backend API is a recipe for disaster.