Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-74908

CVE-2026-74908: Grav Plugin-API XSS Vulnerability

CVE-2026-74908 is a script injection flaw in Grav plugin-api that allows attackers to bypass SVG sanitization using .svgz and .xhtml files. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-74908 Overview

CVE-2026-74908 is a script injection vulnerability [CWE-79] in the Grav plugin-api component before version 1.0.15. The Scalable Vector Graphics (SVG) sanitizer performs an exact-string match against the svg file extension, allowing .svgz and .xhtml files to bypass sanitization entirely. Attackers holding the api.media.write permission can upload files containing executable script payloads. When administrators or site visitors access those files, the payloads execute in the site origin, resulting in stored cross-site scripting.

Critical Impact

Authenticated attackers with media write permission can achieve stored cross-site scripting in the Grav site origin, enabling session theft, administrative action forgery, and content tampering.

Affected Products

  • Grav plugin-api versions prior to 1.0.15
  • Grav CMS installations exposing the media upload API
  • Any Grav deployment granting api.media.write to non-administrative roles

Discovery Timeline

  • 2026-08-18 - CVE-2026-74908 published to the National Vulnerability Database
  • 2026-08-18 - Last updated in NVD database

Technical Details for CVE-2026-74908

Vulnerability Analysis

The Grav plugin-api enforces SVG sanitization to strip active content such as <script> elements and event handler attributes before storing uploaded media. The sanitizer routes files by comparing the uploaded file extension against the literal string svg. Files with different extensions are treated as non-SVG media and skipped by the sanitization step.

Browsers, however, render .svgz files as gzip-compressed SVG documents and treat .xhtml files as XML documents that can embed inline scripts. Both formats execute JavaScript in the origin serving them. Because the sanitizer never inspects these files, malicious script payloads remain intact on disk and execute when the media is fetched.

Exploitation requires an authenticated account with api.media.write. Successful attacks yield stored XSS in the site origin, exposing administrator sessions, cross-site request forgery tokens, and any data reachable from the Document Object Model (DOM).

Root Cause

The root cause is incomplete input validation in the sanitizer dispatch logic. Rather than resolving the effective media type of the upload, the code branches on a case-sensitive extension comparison against svg. Any equivalent renderable format including .svgz and script-capable variants such as .xhtml bypasses the sanitizer.

Attack Vector

An authenticated attacker with api.media.write uploads a crafted .svgz (gzip-compressed SVG containing <script>) or .xhtml file to the media API. Grav stores the file unmodified. When an administrator or visitor navigates to the file URL, the browser executes the embedded script in the Grav site origin. See the GitHub Security Advisory GHSA-66xf-ggf4-6hmc and the VulnCheck Security Advisory for full technical detail.

Detection Methods for CVE-2026-74908

Indicators of Compromise

  • Media directory entries with .svgz or .xhtml extensions written after a plugin-api upload event.
  • SVG or XHTML files whose byte content contains <script, javascript: URIs, or on*= event handler attributes.
  • Media API calls from accounts that do not typically publish content but hold api.media.write.

Detection Strategies

  • Inspect access logs for GET requests to newly uploaded .svgz or .xhtml assets followed by anomalous session activity from administrator accounts.
  • Scan the Grav user/pages and media storage directories for uploaded files whose magic bytes indicate gzip (1f 8b) or XML but whose declared usage is static imagery.
  • Correlate media upload API events with subsequent administrator page views of the uploaded resource.

Monitoring Recommendations

  • Enable audit logging on the Grav Admin panel and forward media API events to a central log store for review.
  • Alert on uploads of .svgz, .xhtml, .xml, or SVG files containing <script> or javascript: tokens.
  • Monitor for outbound requests from administrator browsers to unexpected domains, which can indicate exfiltration triggered by stored XSS.

How to Mitigate CVE-2026-74908

Immediate Actions Required

  • Upgrade Grav plugin-api to version 1.0.15 or later on all environments.
  • Audit accounts that hold the api.media.write permission and revoke access for roles that do not require media publishing.
  • Review the media library for existing .svgz and .xhtml uploads and remove or re-sanitize any files containing active content.

Patch Information

The fix is available in Grav plugin-api1.0.15. The maintainers extended sanitizer dispatch to cover compressed SVG and XHTML variants. Consult the GitHub Security Advisory GHSA-66xf-ggf4-6hmc for the authoritative patch notes.

Workarounds

  • Block uploads of .svgz, .xhtml, and .xml extensions at the reverse proxy or web application firewall until patching is complete.
  • Serve user-uploaded media from a distinct, sandboxed origin so that stored script payloads cannot access the primary Grav session cookie.
  • Enforce a strict Content Security Policy that disallows inline script execution on pages that reference user-supplied media.
bash
# Configuration example: block risky extensions at nginx for user-media paths
location ~* /user/pages/.*\.(svgz|xhtml|xml)$ {
    return 403;
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.