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

CVE-2026-91119: Discourse XSS Vulnerability

CVE-2026-91119 is a stored XSS vulnerability in Discourse that allows attackers to inject malicious HTML through unencoded mention-link attributes. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-91119 Overview

CVE-2026-91119 is a stored HTML injection vulnerability in Discourse, an open-source discussion platform. The flaw affects the topic small-action and nested-activity-log components, which interpolated the free-form action_code_who value directly into mention-link href attributes without URL encoding. A quote-bearing display name could terminate the intended URL attribute and inject attacker-controlled HTML into trusted rendered markup. Although the visible mention text was escaped, the unencoded path component allowed persistent HTML injection whenever another user viewed the affected topic action or activity log. The issue is categorized under [CWE-79] (Improper Neutralization of Input During Web Page Generation).

Critical Impact

Authenticated attackers can inject arbitrary HTML into Discourse topic action and activity log views, affecting any user who renders the compromised content.

Affected Products

  • Discourse versions prior to 2026.1.8
  • Discourse versions prior to 2026.6.3 and 2026.7.2
  • Discourse versions prior to 2026.8.0

Discovery Timeline

  • 2026-09-24 - CVE CVE-2026-91119 published to NVD
  • 2026-09-28 - Last updated in NVD database

Technical Details for CVE-2026-91119

Vulnerability Analysis

The vulnerability resides in two frontend components: small-action.gjs and nested-activity-log/item.gjs. Both components build mention anchors by interpolating the action_code_who value into an href attribute using the userPath() helper. The helper returns the raw username path without URL-encoding reserved characters.

When an attacker crafts a display name containing a double-quote character followed by additional HTML, the browser treats the quote as the end of the href attribute. The remaining content is then parsed as new attributes or elements, resulting in stored HTML injection. The injection persists in topic action metadata and activity logs, so any viewer of the affected content triggers the injected markup.

Root Cause

The root cause is missing URL encoding on the who path component before concatenation into an href attribute. The template distinguishes between group paths and user paths. Group paths were already wrapped in encodeURIComponent(), but the user path branch passed the raw value to userPath(). Downstream escaping of the visible mention text (${escaped}) did not sanitize the attribute value, leaving the sink unprotected.

Attack Vector

An authenticated user can set a display name or trigger an action producing an action_code_who value with embedded quote characters and HTML payload. When the server records the small-action or nested activity log entry, the raw value is persisted. On subsequent renders in any viewer's browser, the attribute terminator breaks out of the href and executes the injected markup within the trusted Discourse origin.

text
// Vulnerable rendering (pre-patch) in small-action.gjs
if (this.isGroupAction) {
  who = `<a class="mention-group" href="/g/${encodeURIComponent(this.who)}">@${escapedWho}</a>`;
} else {
  who = `<a class="mention" href="${userPath(this.who)}">@${escapedWho}</a>`;
}

// Fixed rendering (post-patch)
who = `<a class="mention" href="${userPath(encodeURIComponent(this.who))}">@${escapedWho}</a>`;

Source: GitHub Commit 20dbf11

Detection Methods for CVE-2026-91119

Indicators of Compromise

  • Topic action or activity log entries whose stored action_code_who field contains ", <, >, or javascript: substrings.
  • Unusual DOM structure within .mention or .mention-group anchors on rendered topic pages.
  • Outbound requests from authenticated Discourse sessions to attacker-controlled hosts correlating with topic views.

Detection Strategies

  • Scan the Discourse database for user records and small-action payloads where username or display name fields contain HTML metacharacters.
  • Review web server access logs for POST requests to topic action endpoints that include encoded quote characters in body parameters.
  • Deploy a Content Security Policy (CSP) report-only header to surface attribute-injection attempts in production topic renders.

Monitoring Recommendations

  • Alert on new account creation followed by rapid topic-action generation from the same IP.
  • Monitor Discourse application logs for render warnings on small-action or nested-activity-log components.
  • Track anomalous JavaScript execution origins reported via browser CSP violation endpoints.

How to Mitigate CVE-2026-91119

Immediate Actions Required

  • Upgrade Discourse to 2026.1.8, 2026.6.3, 2026.7.2, or 2026.8.0 depending on the deployed release train.
  • Audit existing user accounts and topic action records for display names containing HTML metacharacters and sanitize or remove offending entries.
  • Restrict new account creation and display-name changes until the patched version is deployed.

Patch Information

The fix wraps the who value with encodeURIComponent() before passing it to userPath() in both frontend/discourse/app/components/post/small-action.gjs and frontend/discourse/app/components/modal/nested-activity-log/item.gjs. Patches are tracked in GitHub Pull Request #42882 and commits 20dbf11, 66653c48, 77a81c7a, and c4748f65. Full details are in the GitHub Security Advisory GHSA-pv3p-p3m9-v8v3.

Workarounds

  • Enforce a strict Content Security Policy that disallows inline scripts and unsafe event handlers on Discourse origins.
  • Temporarily disable topic small-action rendering or the nested activity log feature until upgrading.
  • Reject display names and username inputs containing ", <, >, or control characters at the reverse proxy or WAF layer.
bash
# Example upgrade for a standard Discourse Docker install
cd /var/discourse
git pull
./launcher rebuild app
# Verify the installed version matches a patched release
./launcher logs app | grep -i "discourse version"

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.