Stored XSS and CSRF chain leading to administrator account takeover
Stored XSS in a profile field that executed inside the administration panel. The email change endpoint did not validate any anti-CSRF token. Chained together, the two flaws led to administrator account takeover.
Summary
The “organisation name” field of the user profile was rendered without sanitisation in the administration panel listing. Any registered user could store a payload in that field, and it executed in the administrator’s browser.
The payload changed the administrator’s email address, a change the endpoint accepted without asking for the current password. With that address under their control, the attacker reset the password and signed in.
The severity reflects two conditions: a registered account was enough to plant the payload in a profile, and an administrator ran it by opening the listing.
Technical details
Email change without verification
The endpoint accepted the request on the session cookie alone, with no token and no confirmation:
POST /api/account/update-email
Cookie: [ADMINISTRATOR SESSION]
{ "email": "[ATTACKER EMAIL]" }
-> 200 OK # email updated with no further verificationFull attack chain
The XSS payload issued a fetch() request carrying the administrator’s cookies. The chain ran as follows:
1. The attacker registers an account with organisation = [XSS payload]
2. The administrator visits /admin/users -> the payload executes in their context
3. The script changes the administrator's email via /api/account/update-email
4. The attacker requests a password reset to the email address they control
5. Full administrator account takeoverThe team verified the exploit against a test administrator account created by the client, without accessing any real user data. The case is published anonymised, with the fixes applied and confirmed in the retest.
Impact
- Account takeover of any administrator
- Access to the administration panel and to every record it exposes
- Modification of other users’ data
- Unverified escalation to other internal systems reachable from the panel
Remediation
- User input sanitisation. The HTML of profile fields must be escaped before it is rendered.
- Anti-CSRF tokens. Every state-changing endpoint must validate a token.
- Confirmation for critical changes. An email change must require the current password and be confirmed from the previous address.
- Security headers. Responses must carry a strict Content Security Policy, along with
X-Content-Type-OptionsandX-Frame-Options.
References
More write-ups
Check whether this chain is possible in your administration panel
Tell us which assets you want tested. We reply within 24 hours.