/

CVE-2026-91122

Severity:

HIGH RISK

(8.7)

Stored XSS (CWE-79) in Discourse Video Placeholder

CVE-2026-91122

Deferred

Vulnerability type

Category:

Stored Cross-Site Scripting

CWE:

CWE-79

Impact:

Client-Side Code Execution and Authenticated Session Abuse

Severity:

HIGH RISK

(8.7)

CVSS version:

3.1

Catch this CVE while code is being written

Detect vulnerable code directly in pull requests, so CVEs are fixed before merge.

Summary

Discourse contains a stored cross-site scripting vulnerability in its video placeholder component, where crafted HTML can break out of an attribute and add an attacker-controlled event handler. An authenticated user with default posting privileges may store the content, and the script could execute when another user clicks the video play overlay, particularly when Content Security Policy protections are disabled or relaxed.

Affected context

The issue occurs in Discourse posts containing video placeholders that process insufficiently constrained HTML attributes. Exploitation depends on an authenticated user being able to create or edit posts, another user viewing the post and activating the video overlay, and deployment-level Content Security Policy settings that permit inline event handlers or otherwise fail to block the injected script.

Exploit preconditions

  • Attack surface: User-generated post content and the video placeholder rendering path
  • Required access: An authenticated account with default trust-level posting privileges
  • Trigger point: A viewer opens the affected post and clicks the video play overlay
  • Environmental condition: Content Security Policy must be disabled, relaxed, or otherwise unable to prevent the inline event handler
  • Why exploitation is possible: Crafted placeholder markup can escape its intended attribute context and introduce executable event-handler content

Why this happens

The vulnerability results from improper context-aware output encoding and attribute construction when rendering video placeholders. User-controlled markup is not sufficiently isolated from the surrounding HTML attribute context, allowing an attacker to create an event handler that executes in the origin of the Discourse application. This maps to CWE-79: Improper Neutralization of Input During Web Page Generation, commonly known as cross-site scripting.

Potential impact

  • Arbitrary JavaScript may execute in a victim's browser session
  • Page content and other data accessible to the viewer may be read
  • Authenticated requests could be made on behalf of the viewer
  • Account or moderation actions could be performed if the victim has relevant privileges
  • Sensitive information may be exposed or manipulated

General mitigation guidance

Mitigation generally focuses on preserving strict separation between user content, HTML attributes, and executable code.

Common defensive patterns include:

  • Applying context-appropriate HTML attribute encoding before rendering user-controlled values
  • Constructing video placeholders through safe DOM or templating APIs rather than string concatenation
  • Allowing only a narrowly defined placeholder schema and rejecting unexpected attributes or event-handler names
  • Keeping Content Security Policy enabled with restrictions that prevent inline script and event-handler execution
  • Limiting posting and markup privileges according to least privilege
  • Treating stored user content as untrusted throughout rendering and moderation workflows

How teams detect issues like this

Organizations can look for this class of issue through:

  • Static analysis rules targeting HTML construction with untrusted values
  • Code review checks for attribute-context encoding and string-based template generation
  • Tests that place metacharacters and event-handler-like content in video placeholder attributes
  • Browser security tests verifying that stored content cannot create executable handlers
  • Content Security Policy reporting and monitoring for blocked inline script or event-handler activity
  • Policy enforcement requiring approved sanitizers and safe rendering primitives for user-generated content

Automated security review tools may help identify dangerous output contexts, but findings should be validated against the actual rendering and browser behavior.

Sources

SourceLink
github.comgithub.com/discourse/discourse/commit/05d92b8749f68d2626cbe65ec7adde7562a0283d
github.comgithub.com/discourse/discourse/commit/5674b3e6594825c28d2678e55057fd6802f11031
github.comgithub.com/discourse/discourse/commit/c3993e318e172389be5c98455177876f1dd87dda
github.comgithub.com/discourse/discourse/commit/d7126af3264b672d2201d84c18a37cb8627424a8
github.comgithub.com/discourse/discourse/pull/42882
github.comgithub.com/discourse/discourse/security/advisories/GHSA-8m44-f6g9-7cg7

Frequently asked

questions

It can be exploited through normal Discourse content workflows when an attacker can submit a crafted post and a victim later views and activates the affected video placeholder. The practical impact depends on the instance's Content Security Policy configuration.

Yes. The described attack requires an authenticated user with sufficient default trust-level privileges to store the crafted placeholder in a post.

Treat placeholder values as untrusted, apply context-specific attribute encoding, and build the component with safe rendering APIs that cannot interpret user input as event-handler code.

Combine strict allowlisting and sanitization with secure templating, automated tests for HTML-context breakout, code review rules for dynamic markup, and a restrictive Content Security Policy.

Find out what's already
exploitable in your codebase.