Skip to main content

Grav CMS CVE-2026-42612

HIGH
Cross-site Scripting (XSS) (CWE-79)
2026-05-05 https://github.com/getgrav/grav GHSA-9695-8fr9-hw5q
8.5
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
8.5 HIGH
AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N

Primary rating from GitHub Advisory · only source for this CVE.

CVSS VectorGitHub Advisory

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Confidentiality
High
Integrity
Low
Availability
None

Lifecycle Timeline

2
Source Code Evidence Fetched
May 05, 2026 - 21:48 vuln.today
Analysis Generated
May 05, 2026 - 21:48 vuln.today

DescriptionGitHub Advisory

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
'on_events' => '#(<[^>]+[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 on_events regex in Security::detectXss() no longer requires quotes or whitespace around =. The previous form:

'on_events' => '#(<[^>]+[\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:

'on_events' => '#<[^>]*?[\s\x00-\x20\"\'\/](on\s*[a-z]+|xmlns)\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:

AnalysisAI

Stored cross-site scripting in Grav CMS allows publisher-level authenticated users to execute arbitrary JavaScript in victim browsers by injecting unquoted HTML event handlers that bypass the detectXss() blacklist regex. The flawed pattern failed to detect on* event attributes without surrounding quotes, enabling payloads like <img src=x onerror=eval(...)> to persist in content fields and execute when administrators or other users view the compromised page. Vendor-released patch confirmed in commit 5a12f9be8 (Grav 2.0.0-beta.2), which tightens the on_events regex to flag unquoted attributes, adds dangerous XML namespace tags (svg, math) to the default blocklist, and hardens MediaObjectTrait::attribute() with strict identifier validation. Publicly available exploit code exists. EPSS and KEV data not provided; exploitation requires publisher-level account privileges.

Technical ContextAI

Grav is a flat-file PHP content management system. The vulnerability stems from CWE-79 (Improper Neutralization of Input During Web Page Generation) in the Security::detectXss() function, which uses a regex-based blacklist to sanitize user-submitted HTML. The original on_events pattern required whitespace or quotes immediately after the = sign in event attributes, allowing unquoted syntax like onerror=alert(1) to slip through. HTML5 permits unquoted attribute values containing alphanumerics and a limited set of punctuation, which attackers exploited by encoding payloads via atob() and regex .source to work around character restrictions. The affected package is pkg:composer/getgrav_grav prior to version 2.0.0-beta.2. The commit diff shows the fix also addresses related GitHub Security Advisories (GHSA-c2q3-p4jr-c55f, GHSA-w8cg-7jcj-4vv2) by expanding the dangerous tag list and gating attribute names in MediaObjectTrait to prevent Markdown-based injection vectors. Additionally, the patch hardens SVG dimension parsing against XXE attacks and Installer::unZip against Zip Slip path traversal, indicating a comprehensive security overhaul of the 2.0 branch.

RemediationAI

Upgrade to Grav 2.0.0-beta.2 or later, which includes the fix from commit 5a12f9be8314682c8713e569e330f11805d0a663 (https://github.com/getgrav/grav/commit/5a12f9be8314682c8713e569e330f11805d0a663). The patch replaces the vulnerable on_events regex in Security::detectXss() with a stricter pattern that detects on*= attributes regardless of quoting, expands the default xss_dangerous_tags list to include svg, math, option, and select, and hardens MediaObjectTrait::attribute() to reject event handlers and other dangerous attribute names. For production systems unable to deploy a beta release, apply the commit as a manual patch to system/src/Grav/Common/Security.php and system/config/security.yaml. Compensating controls: restrict publisher role assignment to fully trusted accounts only, enable Content Security Policy headers to mitigate XSS impact (set script-src 'self' and disable 'unsafe-inline'), audit existing content for unquoted event attributes using grep/regex search for patterns like onerror=, onload=, onclick= without surrounding quotes, and configure web application firewalls to block HTML event attributes in POST bodies. Note that CSP is defense-in-depth and may break legitimate inline scripts in Grav themes; test thoroughly. If downgrading to 1.x stable, verify whether the 1.x branch received a backport of this fix via the Grav release notes.

More in PHP

View all
CVE-2012-1823 CRITICAL POC
9.8 May 11

sapi/cgi/cgi_main.c in PHP before 5.3.12 and 5.4.x before 5.4.2, when configured as a CGI script (aka php-cgi), does not

CVE-2016-1555 CRITICAL POC
9.8 Apr 21

(1) boardData102.php, (2) boardData103.php, (3) boardDataJP.php, (4) boardDataNA.php, and (5) boardDataWW.php in Netgear

CVE-2024-11680 CRITICAL POC
9.8 Nov 26

ProjectSend versions prior to r1720 are affected by an improper authentication vulnerability. Rated critical severity (C

CVE-2025-49113 CRITICAL POC
9.9 Jun 02

Roundcube Webmail contains a critical PHP object deserialization vulnerability (CVE-2025-49113, CVSS 9.9) that allows au

CVE-2017-9841 CRITICAL POC
9.8 Jun 27

Util/PHP/eval-stdin.php in PHPUnit before 4.8.28 and 5.x before 5.6.3 allows remote attackers to execute arbitrary PHP c

CVE-2025-0108 HIGH POC
8.8 Feb 12

Palo Alto Networks PAN-OS management web interface contains an authentication bypass allowing unauthenticated attackers

CVE-2021-25298 HIGH POC
8.8 Feb 15

Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re

CVE-2021-25296 HIGH POC
8.8 Feb 15

Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re

CVE-2013-4983 CRITICAL POC
10.0 Sep 10

The get_referers function in /opt/ws/bin/sblistpack in Sophos Web Appliance before 3.7.9.1 and 3.8 before 3.8.1.1 allows

CVE-2023-6553 CRITICAL POC
9.8 Dec 15

The Backup Migration plugin for WordPress is vulnerable to Remote Code Execution in all versions up to, and including, 1

CVE-2024-46506 CRITICAL POC
10.0 May 13

NetAlertX (formerly PiAlert) versions 23.01.14 through 24.x before 24.10.12 allow unauthenticated command injection thro

CVE-2024-8353 CRITICAL POC
9.8 Sep 28

The GiveWP - Donation Plugin and Fundraising Platform plugin for WordPress is vulnerable to PHP Object Injection in all

Share

CVE-2026-42612 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy