Loading...
Skip to main content

CVE-2026-42612 — Vulnerability in getgrav/grav — CVE Details

HIGH

Grav Vulnerable to Publisher-Level Stored XSS via Unquoted Event Attributes

Published May 5, 2026Updated September 10, 2026Source: osv

Summary

### 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`](https://github.com/getgrav/grav/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:** - [`system/src/Grav/Common/Security.php`](https://github.com/getgrav/grav/blob/2.0/system/src/Grav/Common/Security.php). - [`tests/unit/Grav/Common/Security/DetectXssTest.php`](https://github.com/getgrav/grav/blob/2.0/tests/unit/Grav/Common/Security/DetectXssTest.php) — 18 cases: unquoted PoCs, quoted-form regression, safe-content negatives.

Advisory Timeline

  • First published May 5, 2026 (160 days ago).
  • Last revised September 10, 2026 — 127 days after initial publication.

Remediation

Upgrade to the fixed version using your package manager.

Composer
Update getgrav/grav to 2.0.0-beta.2 or later
composer require "getgrav/grav:^2.0.0-beta.2"

After upgrading, run your dependency scanner again to confirm the vulnerability is resolved.

Affected Packages (1)

Affects 1 ecosystem: packagist (1).

PackageEcosystemAffectedFixed In
getgrav/grav
packagist
0.8.0, 0.9.0, 0.9.1, 0.9.10 (+317 more)2.0.0-beta.2

Vulnerability Classification

Common Weakness Enumeration (CWE) identifiers for this vulnerability type.

  • CWE-79
    Cross-site Scripting (XSS)MITRE

CVSS Score Breakdown

What the CVSS (Common Vulnerability Scoring System) 8.5 score means for each attack dimension.

Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Confidentiality
High
Integrity
Low
Availability
None

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N

Frequently Asked Questions

What is CVE-2026-42612?
Grav Vulnerable to Publisher-Level Stored XSS via Unquoted Event Attributes This vulnerability has been assigned a severity rating of HIGH (CVSS score: 8.5/10).
How do I check if my project is affected by CVE-2026-42612?
CVE-2026-42612 affects getgrav/grav. Use GeekWala's free vulnerability scanner to check your dependencies against CVE-2026-42612 and 200,000+ other known vulnerabilities.

Severity & Exploitability

CVSS Score
8.5

High exploitability or significant impact. Prioritize remediation within days.

Also Known As

GHSA-9695-8fr9-hw5q

Related CVEs

  • CVE-2026-75827
    CRITICAL

    Grav: Blueprint dynamic-data bare-function branch is denylist-gated and omits error_log, giving arbitrary file write

  • CVE-2026-65608
    HIGH

    Grav: FlexDirectory::dynamicDataField() executes arbitrary callables from blueprint data with no validation

  • CVE-2025-66296
    HIGH

    Grav vulnerable to Privilege Escalation in Grav Admin: Missing Username Uniqueness Check Allows Admin Account Takeover

  • CVE-2026-64850
    HIGH

    Grav: Remote code execution via unrestricted callable in Blueprint::dynamicData()

  • CVE-2025-66299
    HIGH

    Grav is Vulnerable to Security Sandbox Bypass with SSTI (Server Side Template Injection)

  • CVE-2025-66295
    HIGH

    Grav vulnerable to Path traversal / arbitrary YAML write via user creation leading to Account Takeover / System Corruption

  • CVE-2026-42608
    HIGH

    Grav has Unauthenticated Path Traversal & Arbitrary File Write in its FormFlash component

  • CVE-2026-72695
    HIGH

    Grav: Path Traversal in MediaUploadTrait::deleteFile() Allows Arbitrary File Deletion

Check if you're affected

Scan your dependencies to see if this vulnerability affects your projects.

Scan Your Dependencies