Authorization disclaimer. This walkthrough is exclusively for the intentionally vulnerable PortSwigger Web Security Academy lab linked below. Only test systems you own or are explicitly authorized to assess.
Overview
The profile endpoint is intended to update an email address, but it binds additional client-supplied JSON properties to the user object. Its response reveals a roleid field, and adding "roleid": 2 to the update request promotes the normal lab account to administrator.

Lab objective/setup
Sign in with wiener:peter, obtain administrator privileges, open /admin, and delete the synthetic user carlos.
What I observed
Direct access to /admin was denied to the normal account. Updating the email address generated a JSON response containing the full user representation, including roleid. This both disclosed the privilege attribute and suggested that the endpoint might bind fields beyond the visible form.


Why it is vulnerable
The server maps an untrusted request body onto a privileged domain object without an allowlist. A client should be permitted to change only explicitly supported profile fields; authorization-sensitive properties such as roles must be controlled by a separate privileged workflow.
Walkthrough in the authorized PortSwigger lab
- Log in as
wienerand capturePOST /my-account/change-email. - Add the role property to the JSON body while retaining a valid email value:
1 | {"email":"[email protected]","roleid":2} |
- Replay the request and confirm that the response reports role ID
2. - Visit
/adminand use the lab interface to deletecarlos.



Verification
The same session is denied before the profile update and admitted after the response confirms roleid: 2. Deleting Carlos then causes the Academy to mark the lab solved, tying the outcome to the unauthorized role modification.
Impact and defensive lesson
Mass assignment of privilege fields can produce immediate administrator takeover. Use dedicated request DTOs or explicit field allowlists, ignore unknown properties, keep role management behind privileged endpoints, and avoid returning unnecessary internal account attributes.