Intro:
If you missed our first post introducing the Spot the Bug game, be sure to check it out for context! https://trustfoundry.net/2025/03/12/spot-the-bug-challenge-1/
Then, jump into the challenge below:
Challenge:
Spot the bug in the following pseudocode:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
//parse an HTTP request for adding a new user to the application function add_new_user(add_user_request){ request = request_useradd_parse(add_user_request); //make sure the token's signature is valid session_token_details = token_parse(request.token); if(!validate_signature(session_token_details.signature)){ console.log("Invalid session token, terminating"); return; } user_email = request.email; user_role = request.role; //validate caller permissions if(session_token_details.role = "manager" && user_role != "admin"){ create_user(user_email,user_role); return; } if(session_token_details.role == "admin"){ create_user(user_email,user_role); return; } if(session_token_details.role == "standard" || session_token_details.role == "readonly"){ forbidden_error(); return; } } |
Solution (spoilers below this point):
The code this time is the implementation for a function called add_new_user(). It takes one argument, referred to as add_user_request. As mentioned in the previous post, for these challenges, full context is sacrificed in favor of keeping challenges streamlined. However, this looks like backend code for a web app that will parse out important parts of an HTTP request issued when a user of the application tries to add a new user.
First up after parsing out the user’s request, the session token sent in the request is validated. We don’t have the implementation of validate_signature() to review, so as in all of these challenges, if we can’t see anything about the implementation, it’s probably safe to assume that it should be considered secure for the purposes of the game. (Don’t make such assumptions in the real world!)
Next, the email address and role specified for the user to be added are extracted. Then we get into some logic that checks the role of the user who called this function, as well as the requested role for the user to be added. If the calling user has the “manager” role, they’re intended to be allowed to add any role except for “admin”. If the user has the “admin” role, they can add any role they like. If the user has the “standard” or “readonly” roles, then forbidden_error() is called, indicating that users with these roles are not intended to be able to add new users at all.
The bug exists in the first if block for validating caller permissions. The check on line 14 inadvertently uses assignment, not comparison, so the condition will always pass, leading to an authorization bug. No matter what the role of the user was, session_token_details.role gets assigned the value “manager”, so any calling user, even one with a low-privilege role, will be able to add a new user, so long as the new user’s role is not “admin”. Note that this assignment issue may be language-dependent; when I tried to do this in Python, I received an error, but JavaScript allowed it.
Conclusion:
Thanks for checking out this week’s challenge! We plan to continue sharing these in the coming weeks.