Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessObtain api.media.write API credentials
-
DeliveryUpload SVG with embedded JS payload via POST /api/v1/media
-
ExploitServer stores unmodified SVG
-
ExecutionInduce administrator to open stored SVG URL
-
PersistJavaScript executes in admin browser session
-
ImpactExfiltrate session cookie to attacker endpoint
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 | Exploitation requires the attacker to hold a Grav API account with the api.media.write permission explicitly granted - this permission controls write access to the /api/v1/media endpoint and is not a default or low-barrier condition. Beyond the authenticated upload step, successful exploitation further requires passive user interaction (CVSS UI:P): an administrator must open the malicious SVG file in a browser, either by navigating to its URL directly or by loading a page that embeds it via an <object> or <iframe> element. Exploitation is limited to versions of grav-plugin-api prior to 1.0.3, and only affects deployments where the Grav API plugin is installed and active. The two combined limiting factors - pre-authenticated API access with specific write permissions and administrator browser interaction - substantially reduce the realistic attack surface compared to unauthenticated or no-interaction vulnerabilities. |
| Impact | The CVSS 4.0 score of 5.1 (Medium) is consistent with the attack's realistic constraints. The vector PR:L confirms that an authenticated user with the api.media.write permission is required - unauthenticated exploitation is not possible. UI:P reflects that administrator interaction (opening the SVG in a browser) is a necessary precondition, adding a social engineering dependency. No EPSS score was provided; no KEV listing exists and no public exploit or POC has been identified at time of analysis. The combination of these factors means real-world risk is moderate and largely dependent on two limiting conditions: (1) whether the api.media.write permission is granted to potentially untrusted or compromised accounts, and (2) whether an administrator can be induced to open attacker-uploaded media files. The impact ceiling - session hijacking of an admin account - is meaningfully high if both conditions are met, making this a priority for sites where the API is exposed to external or low-trust authenticated users. The CVSS 4.0 scope metrics (SC:N/SI:N/SA:N) indicate impact is confined to the vulnerable Grav system and does not cascade to other services. |
| Exploit ScenarioDerived | An attacker with api.media.write API access crafts an SVG file embedding a JavaScript payload such as a fetch() call that exfiltrates document.cookie to an attacker-controlled endpoint, then uploads it via a POST request to /api/v1/media. The attacker then sends a Grav administrator a link to the stored SVG file (e.g., in a support ticket, internal message, or by embedding it in a public Grav page via an <object> tag) and waits for the administrator to open it; upon browser rendering, the embedded script executes in the admin's origin context and transmits the session token, granting the attacker full administrative access to the Grav installation. No public POC has been identified, but the technique is well-understood and straightforward for any attacker familiar with SVG-based XSS. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Jul 10, 2026
Stored XSS in the Grav API plugin (getgrav/grav-plugin-api) before version 1.0.3 allows an authenticated attacker holding the api.media.write permission to upload a malicious SVG file that executes arbitrary JavaScript in an administrator's browser session. The POST /api/v1/media endpoint's HandlesMediaUploads::processUploadedFile() method validates only the file extension and never calls Security::sanitizeSVG(), so the uploaded file is stored and served verbatim with Content-Type: image/svg+xml. When an administrator opens the file directly or via an embedded object or iframe, the injected script runs in the admin's authenticated session context, enabling cookie theft and full session hijacking. No public exploit or active exploitation has been identified at time of analysis.
RemediationAI
Upgrade grav-plugin-api to version 1.0.3 or later, which corrects the vulnerability by invoking Security::sanitizeSVG() in the processUploadedFile() method. The vendor advisory is at https://github.com/getgrav/grav/security/advisories/GHSA-7vhm-8x52-2r5p. If immediate upgrade is not possible, restrict the api.media.write permission to only the most trusted, internally managed accounts, eliminating the ability for external or low-privilege users to upload media via the API endpoint. As a secondary compensating control, configure the web server (nginx or Apache) to override the content type for SVG files in the media upload directory, serving them as application/octet-stream or text/plain rather than image/svg+xml; this prevents browser execution of embedded scripts but may break legitimate SVG rendering for users. Note that the content-type override workaround has a trade-off: it will affect all SVG media served from that path, including legitimate files, and does not prevent malicious file storage - it only blocks in-browser execution.
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
Grav is a flat-file CMS that offers an optional REST API via the grav-plugin-api package. The affected endpoint, POST /api/v1/media, delegates file handling to the HandlesMediaUploads trait's processUploadedFile() method, which performs only a file-extension check rather than invoking Grav's built-in Security::sanitizeSVG() sanitization utility. The SVG image format (XML-based) natively supports embedded ECMAScript via <script> tags and event handlers; when a browser fetches such a file served with the image/svg+xml content type, it executes the embedded JavaScript in the context of the serving origin. The root cause is CWE-79 (Improper Neutralization of Input During Web Page Generation - Stored XSS): untrusted content is persisted server-side and later rendered in a privileged browser context without sanitization. The CPE provided (cpe:2.3:a:getgrav:grav:*:*:*:*:*:*:*:*) identifies the Grav ecosystem broadly; the specific vulnerable component is the API plugin, versions prior to 1.0.3.
Know when Grav 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
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N
Network vector via API upload, low privilege (api.media.write account), user interaction required (admin opens SVG), scope changes as script executes in admin browser context, limited C and I impact from session theft.
Primary rating from Vendor (VulnCheck).
CVSS VectorVendor: VulnCheck
Lifecycle Timeline
1DescriptionCVE.org
The Grav API plugin (getgrav/grav-plugin-api) before 1.0.3 fails to sanitize SVG files uploaded through the POST /api/v1/media endpoint. The HandlesMediaUploads::processUploadedFile() method validates only the file extension and never invokes Security::sanitizeSVG(), so an authenticated attacker with the api.media.write permission can upload an SVG containing arbitrary JavaScript. The file is stored unmodified and served with Content-Type: image/svg+xml; when an administrator opens it in a browser (directly or via <object>/<iframe>), the embedded script executes in their session context, enabling cookie theft and session hijacking.
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.
Server-side template injection (SSTI) in Grav (getgrav/grav) prior to 1.8.0-beta.27 allows an authenticated attacker hol
Broken access control in Grav CMS (CWE-285) before 1.8.0-beta.27 lets an authenticated editor-level user escalate their
A Remote Code Execution (RCE) vulnerability in Grav CMS v1.7.48 allows an authenticated admin to upload a malicious plug
Grav is a file-based Web platform. Rated critical severity (CVSS 9.9), this vulnerability is remotely exploitable, low a
GravCMS 1.10.7 allows unauthenticated remote attackers to write arbitrary YAML configuration files, leading to full serv
Remote code execution in Grav CMS 2.0.4 (fixed in 2.0.7) lets an authenticated user holding the admin.pages or api.pages
Remote code execution in Grav CMS before 2.0.15 allows attackers holding page-edit or blueprint-config privileges to wri
Vertical privilege escalation in Grav CMS before 2.0.14 lets a delegated administrator holding only the admin.users perm
Stored cross-site scripting in Grav CMS before 2.0.15 lets authenticated editors smuggle JavaScript event handlers past
Server-side request forgery (SSRF) in Grav CMS versions prior to 1.7.49.5 allows remote authenticated attackers to make
Grav is a file-based Web platform. Prior to 1.8.0-beta.27, Grav CMS is vulnerable to a Server-Side Template Injection (S
Remote code execution in Grav CMS before 2.0.13 allows authenticated low-privilege users to plant and execute arbitrary
EUVD-2026-42905
GHSA-g78v-pr5g-35v2
NVD
CVE.org
EPSS
Vulnrichment
VulDB
Exploit-DB