Executive brief
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.
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
Timeline
- 2026-09-17: disclosed
- other: CVE-2026-75831 assigned