CVE-2026-85600 in Grav
Summary
by MITRE • 09/04/2026
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.
Be aware that VulDB is the high quality source for vulnerability data.
Analysis
by VulDB Data Team • 09/04/2026
The vulnerability identified involves a stored cross-site scripting flaw within Grav Admin, specifically affecting versions prior to 2.0.21 of the getgrav/grav-plugin-admin package. This security issue stems from insufficient input validation and sanitization mechanisms when processing user registration data. An attacker can exploit this weakness by registering a username that contains malicious HTML or JavaScript code instead of standard alphanumeric characters. The core technical flaw lies in the application's failure to properly encode special characters such as double quotes, single quotes, angle brackets, and ampersands during the storage phase. Consequently, when these unsanitized inputs are later retrieved from the database for display within specific administrative interface components, they are rendered directly into the HTML structure without adequate escaping.
The operational impact of this vulnerability is significant because it targets authenticated administrators who possess elevated privileges within the Grav CMS environment. The malicious payload does not execute immediately upon registration but remains dormant in the backend until a privileged user interacts with certain UI surfaces that render the username field. Specific trigger points include the two-factor authentication force-disable confirmation prompt and the editor notice displayed when a page is locked by another user. When an administrator views these screens, their browser parses the injected HTML/JavaScript within the context of the Grav Admin session. This allows the attacker to execute arbitrary scripts with the same permissions as the victim admin, effectively bypassing client-side security controls like the Same-Origin Policy.
From a threat modeling perspective, this vulnerability aligns closely with CWE-79, which classifies improper neutralization of input during web page generation known as Cross-site Scripting (XSS). The attack vector is categorized under Stored XSS because the malicious payload persists in the application's data store and is served to multiple users over time. In terms of adversary tactics, this aligns with MITRE ATT&CK techniques related to Client-side Injection and potentially Account Manipulation if the script facilitates further privilege escalation or persistence mechanisms such as stealing session cookies or performing actions on behalf of the administrator. The ability to execute code in an authenticated admin session poses a severe risk to data integrity and confidentiality within the CMS ecosystem.
To mitigate this vulnerability, administrators must upgrade the Grav Admin plugin to version 2.0.21 or later where the issue has been resolved through improved input sanitization practices. For environments that cannot immediately patch due to compatibility constraints, temporary mitigations include implementing strict Content Security Policy headers to restrict script execution sources and ensuring that all user-supplied data is encoded using context-appropriate encoding methods before being rendered in HTML templates. Developers should also enforce server-side validation rules that reject usernames containing non-alphanumeric characters or specific special symbols unless explicitly required by business logic, thereby reducing the attack surface for injection-based exploits.