CVE-2026-85600: Grav Admin before 2.0.21 Stored XSS via username
Grav Admin (getgrav/grav-plugin-admin2) versions <= 2.0.19 contain a stored cross-site scripting vulnerability in the tHtml() function (src/lib/stores/i18n.svelte.ts), which substitutes untrusted parameters such as usernames into translation templates before parsing the result as markdown. Grav's server-side username validation (DataUser::isValidUsername) blocks filesystem-dangerous characters but not <, >, ", or ', allowing an attacker to register a username containing an HTML payload. When an administrator views a UI surface that renders the username through tHtml()—such as the two-factor force-disable confirmation prompt or the 'page is locked' editor notice—the payload executes in their authenticated session. Fixed in 2.0.21.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
getgrav/grav-plugin-admin2to a version that resolves this vulnerability.Fixed in 2.0.21
Event History
Frequently Asked Questions
Who needs to interact with the malicious account for the payload to run?
An administrator must view an Admin UI element that renders the attacker-controlled username through tHtml(), such as the two-factor force-disable confirmation prompt or the page-locked editor notice. The payload then executes in that administrator's authenticated session.
What does an attacker need to exploit this issue?
The attacker needs to register a username containing an HTML payload and have an administrator encounter a vulnerable UI surface that displays that username. The username validation blocks filesystem-dangerous characters but permits characters including <, >, double quotes, and single quotes.
What version should be used to remediate the issue?
Update Grav Admin to version 2.0.21, which contains the fix. The vulnerability description explicitly identifies versions up to and including 2.0.19 as affected.