CVE-2026-42612: Grav: Publisher-Level Stored XSS via Unquoted Event Attributes

Published May 5, 2026
·
Updated

Summary A stored Cross-Site Scripting (XSS) vulnerability in getgrav/grav allows publisher-level accounts to execute arbitrary JavaScript. The issue arises from a blacklist bypass in the detectXss() function when handling unquoted HTML event attributes.

Details The detectXss() function relies on a blacklist pattern to filter malicious attributes. The specific regex pattern used to match on events is flawed: php 'onevents' => '#(<[^>]+[a-z\x00-\x20\"\'\/])(on[a-z]+|xmlns)\s=[\s|\'\"].[\s|\'\"]>#iUu' This pattern fails to properly identify on event handlers that are constructed without quotation marks. This allows an attacker to completely bypass the filter. Note: It is highly recommended to replace this blacklist approach with a robust, established HTML sanitization library.

PoC An attacker with publisher-level access can reproduce this by injecting the following payload into any vulnerable content field: html <img src=x onerror=eval(atob(/YWxlcnQoZG9jdW1lbnQuY29va2llKQ/.source))> <img width="1889" height="482" alt="image1" src="https://github.com/user-attachments/assets/0f1a339b-25a8-4b6e-91af-8c59e6a39297" /> <img width="3055" height="920" alt="image2" src="https://github.com/user-attachments/assets/12680058-bbb3-4446-b58e-515533bb4e90" /> <img width="2909" height="1339" alt="image3" src="https://github.com/user-attachments/assets/c7ed7e61-8dcf-402d-8589-98d18978c71a" />

Execution Details: The onerror event is written without quotes to bypass the regex. Because unquoted attributes are restricted in their character usage (e.g., the = symbol cannot be used easily), the payload leverages atob() and regex .source to decode the base64 string YWxlcnQoZG9jdW1lbnQuY29va2llKQ (which translates to alert(document.cookie)). The atob() function conveniently auto-completes the necessary = padding for the base64 string.

Impact - Vulnerability Type: Stored Cross-Site Scripting (XSS) - Impacted Parties: Any user (including administrators) who views the compromised content published by the attacker. - Consequences: Attackers can execute malicious scripts in a victim's browser, leading to session hijacking (cookie theft), unauthorized actions.

---

Maintainer note — fix applied (2026-04-24)

Fixed in Grav core on the 2.0 branch: commit 5a12f9be8 — will ship in 2.0.0-beta.2.

What changed: the onevents regex in Security::detectXss() no longer requires quotes or whitespace around =. The previous form:

'onevents' => '#(<[^>]+[\s\x00-\x20\"\'\/])(on\s[a-z]+|xmlns)\s=[\s|\'\"].[\s|\'\"]>#iUu'

required [\s|'"] immediately after the =, so <img src=x onerror=alert(1)> slid past. The new regex drops the value-matching tail entirely and just flags the presence of an on= attribute anywhere inside a tag:

'onevents' => '#<[^>]?\s\x00-\x20\"\'\/\s=#iu'

Detecting the attribute name + = is enough for a tripwire — the trade-off is occasional false positives on legitimate attribute values containing on= substrings, which the maintainer can hand-approve.

This same regex bypass was the detection-layer half of GHSA-c2q3-p4jr-c55f and GHSA-w8cg-7jcj-4vv2; the fix here knocks both down.

Files: - system/src/Grav/Common/Security.php. - tests/unit/Grav/Common/Security/DetectXssTest.php — 18 cases: unquoted PoCs, quoted-form regression, safe-content negatives.

Other sources

Grav is a file-based Web platform. Prior to 2.0.0-beta.2, a stored Cross-Site Scripting (XSS) vulnerability in getgrav/grav allows publisher-level accounts to execute arbitrary JavaScript. The issue arises from a blacklist bypass in the detectXss() function when handling unquoted HTML event attributes. This vulnerability is fixed in 2.0.0-beta.2.

MITRE

Affected Software

3 affected componentsFixes available
composer/getgrav/grav<2.0.0-beta.2
2.0.0-beta.2
getgrav grav<=1.8.0
getgrav grav=2.0.0-beta1

Event History

May 5, 2026
Advisory Published
via GitHub·09:27 PM
Data Sourced
via GitHub·09:27 PM
DescriptionSeverityWeaknessAffected Software
May 11, 2026
CVE Published
via MITRE·03:22 PM
Data Sourced
via MITRE·03:22 PM
DescriptionSeverityWeakness
Data Sourced
via NVD·04:17 PM
RemedyDescriptionSeverityWeaknessAffected Software
Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Frequently Asked Questions

1

What is the severity of CVE-2026-42612?

CVE-2026-42612 has been classified with a critical severity level due to its potential for arbitrary JavaScript execution.

2

How do I fix CVE-2026-42612?

To address CVE-2026-42612, upgrade to version 2.0.0-beta.2 or later of getgrav/grav.

3

Who is affected by CVE-2026-42612?

CVE-2026-42612 affects publisher-level accounts utilizing getgrav/grav.

4

What type of vulnerability is CVE-2026-42612?

CVE-2026-42612 is a stored Cross-Site Scripting (XSS) vulnerability.

5

What causes the CVE-2026-42612 vulnerability?

The vulnerability is caused by a blacklist bypass in the detectXss() function regarding unquoted HTML event attributes.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203