# CVE-2026-75828: Grav stored XSS in XSS detector via unpaired quote bypass

Source: https://junglewise.ai/threats/cve-2026-75828-grav-stored-xss-in-xss-detector-via-unpaired-quote-bypass  
Publisher: Junglewise Threat Intelligence, https://junglewise.ai/threats  
Published: 2026-08-18. Updated: 2026-09-25  
License: CC BY 4.0 with a link back

CVE-2026-75828 · Severity: high · CVSS 8.7 · Published 2026-08-18

Grav, a popular open-source flat-file CMS, has a flaw in its XSS detection mechanism that allows authenticated content editors to inject stored XSS payloads that execute in the browsers of all visitors, including site administrators. An attacker with editor privileges can craft malicious HTML with event handlers (like onerror) preceded by unpaired quotes that the detector misses, bypassing content validation at save time. The injected scripts run with the site's privileges, enabling session hijacking, account takeover, and malware distribution to all users.

Technologies: [getgrav/grav (Packagist)](https://junglewise.ai/threats/technologies/getgrav-grav). Vendors: [Packagist](https://junglewise.ai/threats/vendors/packagist).

## Quick answers

**Is CVE-2026-75828 exploited in the wild?** No. Junglewise Threat Intelligence has no report of CVE-2026-75828 being exploited in the wild.

**How severe is CVE-2026-75828?** High severity, with a CVSS score of 8.7, published 18 August 2026.

**Which products and versions are affected?** getgrav/grav (Packagist) ECOSYSTEM:introduced=0,fixed=2.0.15.

**Is there a fix for CVE-2026-75828?** Yes. getgrav/grav (Packagist): upgrade to 2.0.15 or later. Junglewise finds every place you run it, drafts the upgrade and applies it once you approve.

**How is CVE-2026-75828 attacked?** It is attacked over the network.

**Am I affected by CVE-2026-75828?** Check whether you run getgrav/grav (Packagist) at an affected version. Junglewise does that check for you around the clock: connect your code, cloud and domains, and it matches new vulnerabilities like this one against what you actually run and tells you when one reaches you.

## How to fix

- getgrav/grav (Packagist): upgrade to 2.0.15 or later

  ```sh
  composer require getgrav/grav:^2.0.15
  ```


## Technical details

The vulnerability is a logic error in Grav's `detectXss()` function (Security.php:290) in the `on_events` regex pattern used to detect event-handler attributes. The regex treats any quote character as a string delimiter, but HTML only enters a quoted-value state when a quote appears immediately after `=`. An unpaired quote inside an unquoted attribute value causes the regex to enter an "unterminated string" state from which it cannot advance, allowing a following event handler (e.g., `onerror=`) to be overlooked. Payloads like `&lt;img src=x" onerror=alert(1)&gt;` are stored verbatim in the database because `checkSafety()` at save time (the only XSS guard for non-super editors) relies entirely on `detectXss()`. The injected content is emitted via Twig's `raw` filter and rendered in all visitors' browsers without further validation.

## Affected products

- Getgrav Grav 2.0.13 and likely earlier versions

## Identifiers

- CVE-2026-75828
- GHSA-vfmf-q6x9-cw96

## Timeline

- 2026-09-17: disclosed
- other: CVE-2026-75828 assigned

## Related threats

- [Grav cross-site scripting in Twig sandbox asset methods](https://junglewise.ai/threats/cve-2026-86197-grav-cross-site-scripting-in-twig-sandbox-asset-methods)
- [Grav Twig sandbox config exfiltration via offsetGet and dump filters](https://junglewise.ai/threats/cve-2026-61842-grav-twig-sandbox-config-exfiltration-via-offsetget-and-dump)
- [Grav ZipArchiver decompression bomb via missing extraction limits](https://junglewise.ai/threats/cve-2026-61690-grav-ziparchiver-decompression-bomb-via-missing-extraction-limits)
- [Grav incomplete Twig sandbox denylist information disclosure](https://junglewise.ai/threats/grav-incomplete-twig-sandbox-denylist-information-disclosure-e903bd3b)
- [Grav UserInterface offsetGet/offsetExists Twig sandbox bypass](https://junglewise.ai/threats/grav-userinterface-offsetget-offsetexists-twig-sandbox-bypass-f709468e)
