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

CVE-2026-82396: Sulu CMS Stored XSS Vulnerability

CVE-2026-82396 is a stored XSS vulnerability in Sulu CMS that allows attackers to execute malicious scripts in victims' browsers through uploaded files. This article covers technical details, affected versions, and remediation.

Published:

CVE-2026-82396 Overview

Sulu is an open-source PHP content management system built on the Symfony framework. CVE-2026-82396 is a stored cross-site scripting (XSS) vulnerability [CWE-79] in the MediaStreamController component. The /media/{id}/download/{slug} route and its administration variant honor the inline query parameter for scriptable MIME types, including text/html, application/xhtml+xml, text/xml, and application/xml. An attacker with media upload permission can store a malicious document and share a link with inline=1, causing Sulu to serve the file inline on its own origin. When an authenticated victim opens the link, attacker-controlled JavaScript executes within the victim's Sulu session context.

Critical Impact

Authenticated attackers with upload permission can execute JavaScript in a victim's session, reading data or performing actions as that user on the Sulu origin.

Affected Products

  • Sulu CMS versions prior to 2.6.25
  • Sulu CMS 3.x versions prior to 3.0.8
  • Sulu MediaBundle component (MediaStreamController.php)

Discovery Timeline

  • 2026-08-31 - CVE-2026-82396 published to NVD
  • 2026-09-01 - Last updated in NVD database

Technical Details for CVE-2026-82396

Vulnerability Analysis

The flaw resides in src/Sulu/Bundle/MediaBundle/Controller/MediaStreamController.php. The controller resolves the HTTP Content-Disposition header based on the inline query parameter without filtering scriptable MIME types. When a stored media object has a Content-Type such as text/html or application/xml, requesting the file with inline=1 returns the response with Content-Disposition: inline instead of attachment. Browsers then render the response directly on the Sulu origin, executing any embedded scripts under the victim's session.

Root Cause

The controller lacked a MIME type allowlist for inline rendering. Any media stored with a scriptable content type could be rendered inline on the application origin. This violates the standard mitigation pattern of forcing attachment disposition for user-uploaded content that browsers can interpret as documents.

Attack Vector

Exploitation requires an account with media upload privileges and a victim with an active Sulu session. The attacker uploads an HTML, XHTML, or XML file containing JavaScript, then distributes a URL such as /media/{id}/download/{slug}?inline=1. When the victim clicks the link, the browser renders the attacker-controlled markup on the Sulu origin, granting the script access to session cookies, CSRF tokens, and administrative API endpoints.

php
// Security patch: allowlist of MIME types forced to attachment disposition
class MediaStreamController
{
    /**
     * MIME types a browser renders as a document and would execute on the application
     * origin (stored XSS), so they are forced to "attachment" instead of shown inline.
     * SVG is omitted because uploads are sanitized by the default SvgFileInspector, and
     * standalone scripts are omitted because they do not execute on top-level navigation.
     *
     * @var string[]
     */
    private const DANGEROUS_INLINE_MIME_TYPES = [
        'text/html',
        'application/xhtml+xml',
        'text/xml',
        'application/xml',
    ];

    public function __construct(
        protected DispositionTypeResolver $dispositionTypeResolver,
        protected MediaRepositoryInterface $mediaRepository,

Source: GitHub Commit d061094

Detection Methods for CVE-2026-82396

Indicators of Compromise

  • Media download requests containing the inline=1 query parameter targeting /media/{id}/download/{slug} or the administration variant
  • Uploaded media assets with stored Content-Type values of text/html, application/xhtml+xml, text/xml, or application/xml
  • HTTP responses from Sulu returning Content-Disposition: inline for scriptable MIME types
  • Unexpected outbound requests from authenticated administrator sessions immediately after opening a media link

Detection Strategies

  • Inspect web server access logs for requests to media download routes with inline=1 and correlate against the stored MIME type of the referenced asset
  • Review the Sulu media library for uploads with HTML or XML content types that are not legitimate site assets
  • Alert on session activity where administrative API calls follow a media download request within a short window

Monitoring Recommendations

  • Enable audit logging on media uploads to capture uploader identity, filename, and stored MIME type
  • Monitor Content Security Policy (CSP) violation reports from the Sulu origin for inline script execution events
  • Track access patterns from accounts holding media upload permissions to detect anomalous file staging

How to Mitigate CVE-2026-82396

Immediate Actions Required

  • Upgrade Sulu to version 2.6.25 or 3.0.8 without delay
  • Audit the media library for uploaded files with scriptable MIME types and remove untrusted entries
  • Review and restrict media upload permissions to trusted users only
  • Invalidate active administrative sessions after patching if suspicious uploads are found

Patch Information

The vulnerability is fixed in Sulu 2.6.25 and 3.0.8. The patch introduces a DANGEROUS_INLINE_MIME_TYPES allowlist in MediaStreamController that forces Content-Disposition: attachment for HTML and XML content types regardless of the inline query parameter. See the GitHub Security Advisory GHSA-pp4x-ccxq-6r33, GitHub Release 2.6.25, and GitHub Release 3.0.8.

Workarounds

  • Serve user-uploaded media from a separate, cookieless origin to isolate script execution from the Sulu session
  • Deploy a reverse proxy rule that strips or ignores the inline query parameter on /media/{id}/download/{slug} routes
  • Enforce a strict Content Security Policy on the Sulu origin to block inline script execution
bash
# Example nginx rule to force attachment disposition on media download responses
location ~ ^/media/[0-9]+/download/ {
    proxy_pass http://sulu_backend;
    proxy_hide_header Content-Disposition;
    add_header Content-Disposition "attachment" always;
}

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.