Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
ReconObtain api.media.write API token
-
DeliveryCraft SVG file embedding JavaScript exfiltration payload
-
ExploitUpload via POST /api/v1/media endpoint
-
InstallDistribute stored SVG URL to privileged victim
-
C2Victim opens SVG in browser
-
ExecuteBrowser executes embedded script
-
ImpactAttacker receives exfiltrated session token
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V1 - Encoding and Sanitization Output encoding, context-aware escaping
MITRE ATT&CK
2 techniques across 2 tactics: Initial Access, Execution The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | The attacker must possess a valid API token or credential with the api.media.write permission explicitly granted; this permission is not available to unauthenticated users and is not a default low-privilege role, restricting the attacker pool to authorized API consumers or insider threat actors. After the malicious SVG is uploaded, a second user (the victim) must open the stored file URL in a browser that renders it as an active SVG document. Exploitation is further limited by: (1) deployment scope - only Grav CMS installations with the API plugin installed and the API endpoint network-accessible are affected; (2) the need for victim interaction, meaning automated mass exploitation without social engineering is not feasible; and (3) the absence of a scope change to the underlying server, so the attacker cannot leverage this path alone to achieve server-side code execution. |
| Impact | The NVD CVSS 3.1 base score of 4.6 (AV:N/AC:L/PR:L/UI:R/S:U/C:L/I:L/A:N) accurately reflects the primary limiting factors: the attacker must hold api.media.write permission (PR:L), and a victim must actively open the stored SVG (UI:R). These prerequisites meaningfully constrain the realistic attacker population to compromised API credential holders or malicious insiders - the vulnerability is not exploitable by anonymous external attackers. The NVD assignment of S:U (unchanged scope) is debatable; stored XSS that executes in a separate user's browser session represents a classical scope change, and S:C would yield a higher score - this is flagged as an area where analysts may differ. No EPSS data was included in the provided intelligence, the CVE is not listed in CISA KEV, and no public POC has been identified. Real-world risk is moderate-low: the api.media.write permission gate substantially reduces exposure, and the primary impact (session hijacking, impersonation) is meaningful but does not include remote code execution or data destruction. Organizations running Grav with the API plugin exposed to untrusted API consumers represent the highest-risk deployments. |
| Exploit ScenarioDerived | An attacker who has obtained valid API credentials with api.media.write permission crafts an SVG file containing a JavaScript payload that exfiltrates the victim's session cookie or JWT token to an attacker-controlled server. After uploading the file via POST /api/v1/media, the attacker distributes the resulting SVG URL to a privileged administrator (e.g., via a phishing message referencing a legitimate-looking media asset). When the administrator opens the URL in a browser, the SVG is rendered as an active document, the script executes, and session credentials are delivered to the attacker - who can then replay them to take over the administrator's account. No public POC has been identified at time of analysis. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Aug 19, 2026
Stored cross-site scripting in the Grav API Plugin (all versions prior to 1.0.2) allows an authenticated attacker holding api.media.write permission to upload a malicious SVG file whose embedded JavaScript executes in any victim's browser that opens the file. The upload pipeline in HandlesMediaUploads::processUploadedFile() checks the SVG filename extension but omits the Security::sanitizeSVG() call, so script content passes through unmodified and is later served as Content-Type: image/svg+xml, triggering browser-side execution. Successful exploitation enables session token theft and impersonation of the victim; no public exploit has been identified at time of analysis, and vendor-released patch version 1.0.2 is available.
RemediationAI
Upgrade to Grav API Plugin version 1.0.2, which resolves the vulnerability by invoking Security::sanitizeSVG() within the upload pipeline so that embedded scripts are stripped before the file is persisted. The patched release is available at https://github.com/getgrav/grav-plugin-api/releases/tag/1.0.2; the fixing commit is https://github.com/getgrav/grav-plugin-api/commit/d25eedb84a387f2c71b12a374f2a4b3d74339a7e. If an immediate upgrade is not feasible, revoke or restrict api.media.write permissions to the minimum set of trusted accounts - note that this will break any legitimate API-driven media management workflows for affected consumers. As a secondary control, deploy a Content-Security-Policy response header that prohibits inline script execution (e.g., script-src 'self'); this would suppress SVG-delivered XSS in victims' browsers even if a malicious file were already stored, at the potential cost of breaking any in-app inline scripting. Note that version 1.0.2 also addresses two additional security issues: JWT secret exposure via the config file and a double-extension upload bypass - upgrading resolves all three.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
The affected component is the Grav API Plugin (CPE: cpe:2.3:a:getgrav:grav-plugin-api:*:*:*:*:*:*:*:*), an optional RESTful extension for the Grav flat-file CMS that exposes headless content management over a JSON API. The POST /api/v1/media endpoint routes uploaded files through HandlesMediaUploads::processUploadedFile(), which performs filename extension inspection to identify SVGs but never calls Grav's Security::sanitizeSVG() method - the function responsible for stripping embedded script elements, javascript: URIs, and event handler attributes from SVG markup before persistence. CWE-79 (Improper Neutralization of Input During Web Page Generation - Cross-Site Scripting) captures the root cause precisely: untrusted attacker-supplied content is written to storage and subsequently served to users without sanitization. Browsers treat SVG served with Content-Type: image/svg+xml as an active document, so any embedded JavaScript executes in the victim's browser security context with access to cookies and session state scoped to the serving origin.
Know when Grav Plugin Api gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:L/PR:L/UI:R/S:U/C:L/I:L/A:N
Stored XSS executing in a victim's browser context crosses security scope (S:C); PR:L reflects the mandatory api.media.write credential requirement.
Primary rating from Vendor (GitHub_M).
CVSS VectorVendor: GitHub_M
Lifecycle Timeline
1DescriptionCVE.org
Grav API Plugin is a RESTful API for Grav CMS that provides full headless access to your site's content. Prior to 1.0.2, the Grav API plugin POST /api/v1/media pipeline in HandlesMediaUploads::processUploadedFile() validates an SVG filename extension but does not invoke Security::sanitizeSVG(). An attacker with api.media.write permission can store an SVG containing JavaScript, and the server returns the file as Content-Type: image/svg+xml so the script executes when a victim opens it, allowing session data theft and authenticated actions. This issue is fixed in version 1.0.2.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Cross-Site Scripting occurs when an application accepts untrusted data and sends it to a web browser without proper validation or encoding.
More in Grav Plugin Api
View allHost header injection in the Grav API plugin's forgot-password endpoint allows unauthenticated remote attackers to redir
Server-Side Request Forgery in the Grav API plugin (grav-plugin-api) for Grav CMS before 1.0.6 lets a caller holding the
Unauthenticated resource exhaustion in the Grav API plugin (grav-plugin-api) before 1.0.42 allows any remote attacker wh
Privilege escalation in Grav API Plugin (all versions before 1.0.6) allows any authenticated user holding the api.users.
Privilege escalation in grav-plugin-api before 1.0.20 allows a low-privileged API manager to self-create a super-admin a
Privilege escalation in grav-plugin-api before 1.0.20 allows authenticated API users holding api.access and api.users.wr
Privilege escalation in the Grav API plugin (grav-plugin-api) before 1.0.36 allows an account that already holds the api
Permissive CORS misconfiguration in the Grav API Plugin (all versions prior to 1.0.0-rc.16) allows cross-origin JavaScri
Scope enforcement is entirely absent in the Grav API Plugin prior to 1.0.6, meaning any scoped API key silently exercise
JWT bearer token leakage in the Grav API Plugin for Grav CMS (prior to 1.0.0-rc.16) exposes valid access tokens to any p
Disabled accounts in Grav API plugin versions before 1.0.36 can continue to access API endpoints because SessionAuthenti
Stored XSS in Grav CMS's grav-plugin-api (Admin2) allows a low-privileged editor to persist malicious JavaScript in page
EUVD-2026-62533
NVD
CVE.org
EPSS
Vulnrichment
GitHub
Exploit-DB