CVE-2026-75831: Grav stored XSS via Markdown audio/video source URL

CVE-2026-75831 · Severity: high · CVSS 7.6 · Published 2026-08-18

Grav's audio and video embedding feature in Markdown renders media URLs without proper HTML encoding, allowing content authors to inject executable JavaScript that runs in the browser of anyone viewing the page, including administrators. An attacker with page-editing privileges can embed malicious audio or video files that execute arbitrary scripts in visitors' sessions, potentially compromising administrator accounts.

Technologies: Grav, getgrav/grav (Packagist). Vendors: Grav, Packagist.

Quick answers

Is CVE-2026-75831 exploited in the wild?
No. Junglewise Threat Intelligence has no report of CVE-2026-75831 being exploited in the wild.
How severe is CVE-2026-75831?
High severity, with a CVSS score of 7.6, published 18 August 2026.
Which products and versions are affected?
Grav 2.0.13 and earlier, including develop branch; getgrav/grav (Packagist) <= 2.0.14, ECOSYSTEM:introduced=0,fixed=2.0.15.
Is there a fix for CVE-2026-75831?
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-75831 attacked?
It is attacked over the network, in a web application.
Am I affected by CVE-2026-75831?
Check whether you run Grav or 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
    composer require getgrav/grav:^2.0.15

Technical details

A stored cross-site scripting (XSS) vulnerability exists in Grav's AudioMediaTrait and VideoMediaTrait classes, where the `sourceParsedownElement()` method concatenates media URLs directly into a Parsedown rawHtml element without HTML escaping. The vulnerable code builds `<source src="$location">` by string concatenation, where $location includes the URL fragment unencoded. An attacker can inject markup like `song.mp3#"><svg/onload=alert(1)>` to break out of the src attribute and inject arbitrary HTML/JavaScript. The fragment passes through Excerpts.php which decodes it with htmlspecialchars_decode and urldecode, stripping prior escaping. The built-in tagfilter fails to block `<svg>` and `<img>` tags, allowing event handlers like `onload` to execute. The fix requires escaping $location with htmlspecialchars() before concatenation or using Parsedown's attribute-escaping mechanism instead of rawHtml.

Affected products

  • Grav Grav 2.0.13 and earlier, including develop branch

Identifiers

  • CVE-2026-75831
  • GHSA-6qw9-4vv5-jr97

Timeline

  • 2026-09-17: disclosed
  • other: CVE-2026-75831 assigned

This page as Markdown. Free to reuse under CC BY 4.0 with a link back.