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

CVE-2026-93505: SveltyCMS SVG Upload XSS Vulnerability

CVE-2026-93505 is a cross-site scripting flaw in SveltyCMS 0.0.6 affecting SVG media uploads that enables remote attackers to inject malicious scripts. This post explains its impact, affected versions, and mitigation steps.

Updated:

CVE-2026-93505 Overview

CVE-2026-93505 is a stored cross-site scripting (XSS) vulnerability in SveltyCMS version 0.0.6. The flaw resides in the SVG Media Upload component, specifically in src/utils/media/media-service.server.ts. An authenticated remote attacker can upload a crafted SVG file that bypasses sanitization, injecting executable JavaScript that runs in the browser context of any user viewing the file.

The issue is classified as [CWE-79] Improper Neutralization of Input During Web Page Generation. The maintainers have published a patch under commit 05b4f9efeb79e9d72a693232334d7529687f896f, which routes all .svg uploads through a sanitization pipeline and adds Content Security Policy (CSP) restrictions on the file serving routes.

Critical Impact

Attackers with upload privileges can persist malicious JavaScript in SVG assets, leading to session theft, account takeover, and administrative privilege abuse when victims render the file.

Affected Products

  • SveltyCMS 0.0.6
  • Component: SVG Media Upload handler (src/utils/media/media-service.server.ts)
  • Deployments serving user-uploaded SVG files through /files/ routes

Discovery Timeline

  • 2026-09-18 - CVE-2026-93505 published to NVD
  • 2026-09-18 - Last updated in NVD database
  • Patch commit - 05b4f9efeb79e9d72a693232334d7529687f896f merged to the SveltyCMS repository

Technical Details for CVE-2026-93505

Vulnerability Analysis

SveltyCMS accepts SVG files through its media upload endpoint. Because SVG is an XML-based format, it can embed <script> elements, event handlers such as onload, and foreign object payloads that execute JavaScript when the file is rendered in a browser. The pre-patch implementation in media-service.server.ts did not consistently sanitize SVG content before persisting or serving it.

According to the remediation commit message, a large-file stream path bypassed the sanitizer entirely. Any SVG exceeding an internal streaming threshold was written to storage without passing through bufferAndSanitizeSvg(). This gap allowed attackers to smuggle script-bearing SVGs into the media library. When rendered from the /files/ route, the browser executed the embedded JavaScript in the origin of the SveltyCMS deployment.

Root Cause

The root cause is inconsistent enforcement of SVG sanitization across upload code paths. The stream-based upload branch skipped bufferAndSanitizeSvg(), and the /files/ serving route did not emit a restrictive Content Security Policy. The patch closes both gaps by forcing every SVG through the sanitizer, enforcing a MAX_SVG_BYTES ceiling of 5 MiB, and adding script-src 'none' on file responses.

Attack Vector

Exploitation requires network access to the SveltyCMS instance and authenticated privileges sufficient to upload media. The attacker crafts an SVG containing JavaScript payloads, uploads it through the media interface, and then induces a victim to view the asset. User interaction is required, since the payload triggers when the victim loads the SVG in a browser context. Successful exploitation yields script execution under the SveltyCMS origin, enabling cookie theft, CSRF against privileged endpoints, and defacement.

text
// Patch summary from commit 05b4f9efeb79e9d72a693232334d7529687f896f
Stored XSS via SVG Upload (CWE-79):
- Closed large-file stream bypass by forcing all `.svg` uploads
  through `bufferAndSanitizeSvg()`.
- Enforced strict `MAX_SVG_BYTES` (5 MiB) ceiling.
- Added CSP `script-src 'none'` to `/files/` serving routes.

// Source: https://github.com/SveltyCMS/SveltyCMS/commit/05b4f9efeb79e9d72a693232334d7529687f896f

Detection Methods for CVE-2026-93505

Indicators of Compromise

  • SVG files in the media library containing <script>, onload, onerror, <foreignObject>, or javascript: URI schemes
  • Upload requests targeting the media endpoint with Content-Type: image/svg+xml and payload sizes near or above the previous stream threshold
  • Unexpected outbound requests originating from browsers that recently rendered SVG assets served from /files/
  • New or modified admin accounts shortly after SVG asset views by privileged users

Detection Strategies

  • Perform static inspection of stored SVG assets for script-capable elements and event handler attributes before serving them to users
  • Monitor web server logs for POSTs to the SveltyCMS media upload route followed by GETs to /files/ routes returning image/svg+xml
  • Alert on responses from /files/ that lack the Content-Security-Policy: script-src 'none' header on patched deployments

Monitoring Recommendations

  • Ingest SveltyCMS application logs and web server access logs into a centralized analytics platform to correlate upload and retrieval activity
  • Track session anomalies for administrative users following media views, including sudden role changes or token reuse from new IPs
  • Baseline the average SVG file size and flag uploads that exceed 1 MiB for manual review pending patch deployment

How to Mitigate CVE-2026-93505

Immediate Actions Required

  • Apply commit 05b4f9efeb79e9d72a693232334d7529687f896f from the SveltyCMS repository or upgrade to a release that includes it
  • Audit the existing media library and remove or re-sanitize any SVG files uploaded before the patch was applied
  • Restrict media upload permissions to the minimum set of trusted roles until the fix is deployed
  • Rotate session tokens and API keys for users who may have rendered untrusted SVG assets

Patch Information

The fix is delivered in commit 05b4f9efeb79e9d72a693232334d7529687f896f. It forces all .svg uploads through bufferAndSanitizeSvg(), enforces a 5 MiB ceiling via MAX_SVG_BYTES, and adds Content-Security-Policy: script-src 'none' to responses from /files/ routes. The same commit also addresses related privilege escalation ([CWE-269]) and server-side request forgery ([CWE-918]) issues. See the patch commit and the VulDB entry for CVE-2026-93505 for details.

Workarounds

  • Block SVG uploads at a reverse proxy or web application firewall until the patch is applied
  • Serve user-uploaded content from a sandboxed domain distinct from the SveltyCMS application origin
  • Add a Content-Security-Policy: script-src 'none'; sandbox response header on media serving routes
  • Rewrite SVG responses to Content-Type: application/octet-stream with Content-Disposition: attachment to prevent inline browser rendering
bash
# Example nginx hardening for /files/ routes serving user-uploaded media
location /files/ {
    add_header Content-Security-Policy "script-src 'none'; sandbox" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Content-Disposition "attachment" always;

    # Reject SVG uploads at the edge until patch is deployed
    if ($request_method = POST) {
        if ($content_type ~* "image/svg\+xml") {
            return 415;
        }
    }
}

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

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.