Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessAuthenticate as low-privileged user
-
DeliverySet display name with quote-bearing href breakout payload
-
ExploitName stored as action_code_who in small-action/activity log
-
ExecutionVictim views affected topic action
-
PersistUnencoded value breaks out of mention href
-
ImpactAttacker HTML injected into trusted rendered markup
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 | Requires an authenticated account (PR:L) whose attacker-controlled display name propagates into the free-form action_code_who value rendered by the topic small-action or nested-activity-log components; the payload must contain a double-quote to terminate the mention-link href attribute. Exploitation triggers passively when another user views the affected topic action or activity log (UI:N for the attacker). Limiting factors: only versions before 2026.1.8/2026.6.3/2026.7.2/2026.8.0 are affected; the visible mention text is already escaped so only the href path component is injectable; and Discourse's default Content-Security-Policy restricts inline script/event handlers, so full JavaScript execution is realistic mainly on instances that relax or disable CSP, with default deployments limited to trusted-HTML/element injection. |
| Impact | This is a genuine but moderate-severity issue, not a top-priority emergency. The CVSS 3.1 vector (AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N = 6.4) reflects a network-reachable, low-complexity stored injection requiring only a low-privileged authenticated account (any user able to set a quote-bearing display name that becomes action_code_who) and no victim interaction beyond viewing the affected topic action or activity log. No EPSS score, no CISA KEV listing, and no public exploit code were provided, so exploitation status is: no public exploit identified at time of analysis. Critically, the description and PR diff show this is stored HTML injection into TRUSTED rendered markup - the visible mention text is already HTML-escaped, and the demonstrated payload is an <img> attribute breakout ( |
| Exploit ScenarioDerived | A low-privileged authenticated Discourse user sets a display name containing a double-quote breakout payload (e.g. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Sep 24, 2026
Stored HTML injection in Discourse's topic small-action and nested-activity-log components lets an authenticated user with a crafted display name break out of the mention-link href attribute and inject arbitrary markup into the trusted page for anyone who later views the affected topic action or activity log. Attackers need only an account and a quote-bearing name (or any attacker-influenced action_code_who value); the victim requires no interaction beyond loading the topic, and the payload persists in stored topic history. The issue is limited to Unicode-encoded href paths in versions before 2026.1.8, 2026.6.3, 2026.7.2 and 2026.8.0, and no public exploit code or confirmed active exploitation was identified at time of analysis; Discourse's default Content-Security-Policy means full script execution is realistic mainly on instances that weaken or disable CSP, so the practical impact is moderate rather than critical.
RemediationAI
Vendor-released patch: upgrade to Discourse 2026.1.8, 2026.6.3, 2026.7.2 or 2026.8.0, the versions that fix CVE-2026-91119; the relevant changes are the encodeURIComponent() wrapping of the mention href path in the small-action and nested-activity-log components, delivered in pull request https://github.com/discourse/discourse/pull/42882 (commits 20dbf112760eb1d6a58f2e49aeef7546898b6f1c, 66653c484cfb91bc346f9a326f6945387f17b035, 77a81c7a3a7ff9e94b355e32b8f379f2d389e05a, c4748f651d9d2f3a6dd3106a4d5564536c645168) and documented in GHSA-pv3p-p3m9-v8v3. Until the upgrade can be staged, the highest-value compensating control is to preserve Discourse's default Content-Security-Policy rather than relaxing it - the assessor notes that inline script and event handlers are blocked under default CSP, so instances that have added unsafe-inline or otherwise weakened CSP should revert that change first; the trade-off is that any custom themes, plugins or embedded widgets relying on inline script may stop working and will need refactoring. Operators can also reduce the attack surface by tightening who may set or change display names (requiring staff approval for name changes, or disabling self-service name edits) so attacker-controlled values cannot reach action_code_who; the trade-off is added moderation overhead and user friction. Because the payload is stored and renders passively when a topic action or activity log is viewed, moderators should review existing topic action and activity-log content for suspicious display names containing quote characters, and audit the user list for names with attribute-breaking characters; note that this is a detection and cleanup measure only, not a substitute for patching. If a full PHP/Ruby-side mitigation is required before the release upgrade lands, apply the upstream diff to the two .gjs components (encodeURIComponent around the userPath argument) and the sanitize_sql_like() change in app/models/concerns/has_url.rb as a local patch, accepting the maintenance burden of carrying an out-of-band change.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 4 packages in euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
The flaw is a classic CWE-79 output-encoding failure inside Discourse's Glimmer (Ember) frontend components. In app/components/post/small-action.gjs and app/components/modal/nested-activity-log/item.gjs, the free-form action_code_who string was passed through userPath() and interpolated directly into an HTML string - <a class="mention" href="${userPath(who)}">@${escaped}</a> - while only the visible anchor text was escaped. Because the path component was never URL-encoded, a display name containing a double quote terminated the href attribute early, allowing arbitrary attributes and elements (for example an onerror-bearing img) to be injected into markup the application treats as trusted. The upstream fix (PR 42882, commits 20dbf112, 66653c48, 77a81c7a, c4748f65) applies encodeURIComponent(who) to the href path while keeping run-time escaping of the label, and the accompanying regression tests assert that a payload of "><img src=x> yields href /u/%22%3E%3Cimg%20src%3Dx%3E with no injected element. The same pull request bundles adjacent hardening: sanitize_sql_like(data[1]) in app/models/concerns/has_url.rb to prevent LIKE wildcard abuse in URL lookups, a check rejecting video-placeholder sources containing a double quote to stop attribute breakout via data-video-src, and additional sanitizer tests blocking iframe URLs with URL-encoded path traversal (%2e%2e) under allowed_iframes. The affected component set is captured by the CPE entry cpe:2.3:a:discourse:discourse:*:*:*:*:*:*:*:* (all tracks prior to the patched releases). The independent assessment rates this CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N, i.e. an authenticated attacker (PR:L), no victim interaction (UI:N), scope change because injected markup escapes the intended anchor context, with low confidentiality and integrity impact and no availability impact.
Know when Discourse 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
AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N
Network-reachable stored injection needing only a low-privileged account (PR:L) and no victim interaction; injection into trusted cross-user markup gives S:C with limited C:L/I:L since default CSP curbs full script execution.
Primary rating from Vendor (GitHub_M).
CVSS VectorVendor: GitHub_M
Lifecycle Timeline
2DescriptionCVE.org
Discourse is an open-source discussion platform. Prior to 2026.1.8, 2026.6.3, 2026.7.2, and 2026.8.0, the topic small-action and nested-activity-log components interpolated the free-form action_code_who value into mention-link href attributes without URL encoding. A quote-bearing display name could terminate the intended URL attribute and inject attacker-controlled elements into the trusted rendered markup. Although the visible mention text was escaped, the unencoded path component allowed stored HTML injection when another user viewed the affected topic action or activity log. This issue is fixed in versions 2026.1.8, 2026.6.3, 2026.7.2, and 2026.8.0.
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.
Discourse versions prior to 3.5.0.beta6 contain a reflected cross-site scripting (XSS) vulnerability in social login fun
discourse-bbcode is the official BBCode plugin for Discourse. Rated critical severity (CVSS 9.8), this vulnerability is
Unauthorized information disclosure in Discourse discussion platform versions prior to 2026.3.0-latest.1, 2026.2.1, and
Discourse is an open source platform for community discussion. Rated high severity (CVSS 8.2), this vulnerability is rem
Discourse versions prior to 2025.12.2, 2026.1.1, and 2026.2.0 contain an insecure direct object reference (IDOR) in the
In Discourse 2.7.0 through beta1, a rate-limit bypass leads to a bypass of the 2FA requirement for certain forms. Rated
Unauthenticated attackers can submit forged webhook payloads to multiple email provider integrations in Discourse versio
Discourse is an open-source discussion platform. Rated medium severity (CVSS 6.5), this vulnerability is remotely exploi
Discourse is an open source platform for community discussion. Rated medium severity (CVSS 5.9), this vulnerability is r
Discourse versions prior to 3.4.4 (stable), 3.5.0.beta5 (beta), and 3.5.0.beta6-dev (tests-passed) contain a critical vu
Discourse is an open source platform for community discussion. Rated critical severity (CVSS 9.8), this vulnerability is
Discourse Patreon enables syncronization between Discourse Groups and Patreon rewards. Rated critical severity (CVSS 9.8
EUVD-2026-86307
NVD
CVE.org
EPSS
GitHub
Exploit-DB