CVE-2026-91119
Executive Summary
CVE-2026-91119 is a stored HTML injection vulnerability in Discourse, an open-source discussion platform. Prior to the fixed releases (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, allowing an attacker with a low-privileged account to inject markup that renders in trusted pages when other users view the affected topic action or activity log. The issue affects any Discourse instance running a vulnerable version and carries a CVSS v3.1 base score of 6.4 (Medium), with scope change indicating potential impact beyond the vulnerable component.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
CVE-2026-91119 is classified as CWE-79 (Improper Neutralization of Input During Web Page Generation, i.e., cross-site scripting / HTML injection). The defect is a classic context-mismatch encoding failure: a free-form, user-influenced value is placed into an HTML attribute context without the encoding appropriate to that context.
Specifically, per the NVD description, the action_code_who value is interpolated into mention-link href attributes inside the following components:
- topic small-action
- nested-activity-log
The rendering pipeline escapes the visible mention text, but the unencoded path component — the portion placed into the href attribute — is not URL-encoded. Because an href attribute is double-quoted HTML, a display name containing a quote character can terminate the intended attribute value and allow an attacker to append attacker-controlled elements into the rendered markup. The result is stored HTML injection: the injected content is persisted and executes/renders when another user views the affected topic action or activity log.
Key technical characteristics:
- Attack vector: Network (AV:N) — exploitation occurs through normal web/HTTP interaction with the Discourse instance.
- Privileges required: Low (PR:L) — the actor needs a regular authenticated account to set a display name / action actor value.
- User interaction: None (UI:N) — the victim does not need to click a special link; merely viewing the affected action or activity log is sufficient per the description.
- Scope: Changed (S:C) — the vulnerable component can affect resources beyond its security scope, consistent with injected markup that runs in the security context of other users/sessions.
- Confidentiality/Integrity: Low/Low (C:L/I:L) — consistent with HTML/script injection into trusted pages.
- Availability: None (A:N).
- Root cause: Missing URL/attribute encoding of the free-form
action_code_whopath component, combined with a mismatched escaping strategy (text escaped, attribute not).
No public proof-of-concept, exploit code, or Nuclei template is available in the provided data. The description is sufficient to characterize the vulnerability class and mechanism, but it does not enumerate specific functions, endpoints, or parameter names beyond action_code_who and the two components (topic small-action, nested-activity-log). No further implementation specifics should be inferred.
Exploitation Scenarios
Note: No public PoC exists in the provided data. The chain below is inferred at the vulnerability-class level from the NVD description and must not be treated as a confirmed end-to-end exploit sequence.
Reconnaissance / target identification. An attacker identifies an internet- or intranet-reachable Discourse instance running a version prior to 2026.1.8, 2026.6.3, 2026.7.2, or 2026.8.0. Identification can leverage standard product fingerprinting (Discourse is a well-known platform). The attacker registers or obtains a low-privileged account (PR:L).
Triggering the specific flaw class. The attacker supplies a crafted value that will later populate the free-form
action_code_whofield — the display-name field that Discourse interpolates into mention-linkhrefattributes within the topic small-action and nested-activity-log components. The injected value exploits the missing URL encoding: because the value is placed unencoded into a double-quotedhrefattribute, a quote-bearing name can close the attribute early and cause the remaining attacker-supplied content to be parsed as new markup rather than as part of the link.Payload / execution method (class level). The payload is a crafted display name (or equivalently influenced actor value) containing a quote character followed by markup, such that the attribute terminates and attacker-controlled elements are inserted into the trusted rendered markup. The visible mention text may still be escaped; the injection occurs through the unencoded path component of the
href. This is a stored (persistent) injection — the injected markup is saved and rendered later.Post-exploitation impact. When another user (e.g., a moderator/administrator or any member) views the affected topic action or nested activity log, the attacker-injected markup is rendered in the trusted origin. Depending on the injected element type, impact ranges from UI redirection/spoofing to session- or CSRF-relevant actions in the victim's authenticated context, consistent with C:L/I:L and S:C. Because the flaw is stored, it can persist until the malicious display name/value is changed or the content is sanitized.
Impact Assessment
- CVSS v3.1 base score: 6.4 (Medium) —
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N. - Attack surface: Any Discourse instance exposing topic actions and activity logs to users who view them, including community forums, support portals, and internal collaboration deployments.
- Blast radius: Broadcast within an instance — a single crafted value is stored and rendered to all users who view the affected action/activity log. Scope is Changed, so impact is not confined to the injecting user's account.
- Business impact: Trusted-page HTML injection can degrade user trust, enable content/UI spoofing and redirection, and in higher-impact constructions support actions in a victim's authenticated session context. Low confidentiality/integrity ratings indicate bounded but non-trivial impact.
- Exploitability inputs: A PoC and exploit code are absent, and no EPSS score is available, so real-world exploitation likelihood cannot be quantified from the provided data. CISA KEV status: NO.
Detection Guidance
Sigma Rule
title: Potential Discourse HTML Injection in Action/Actor Value (CVE-2026-91119)
id: 5b0e4c2a-9111-9cve-2026-91119-0001
status: experimental
description: Detects HTTP requests or logged events containing quote-bearing values associated with the action_code_who field in Discourse, indicative of HTML injection attempts targeting small-action / activity-log components.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-91119
author: valtersit.com
date: 2026/01/01
logsource:
category: web
product: discourse
detection:
keywords:
- 'action_code_who'
suspicious_quote:
- '" onmouseover='
- '" onerror='
- '" onload='
- '"><'
- '"></'
- '" style='
condition: keywords and suspicious_quote
falsepositives:
- Legitimate display names containing double quotes with benign following text
level: medium
tags:
- attack.t1059
- cve.2026.91119
- cwe.79
YARA Rule
rule CVE_2026_91119_Discourse_HTML_Injection
{
meta:
description = "Detects quote-bearing payload patterns consistent with CVE-2026-91119 HTML injection via action_code_who in Discourse"
author = "valtersit.com"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-91119"
date = "2026-01-01"
cve = "CVE-2026-91119"
strings:
$a = "action_code_who"
$q1 = /"[\s]*on[a-z]+[\s]*=/
$q2 = "\"><"
$q3 = "\"></"
condition:
$a and any of ($q*)
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-91119 Discourse HTML Injection via action_code_who"; flow:established,to_server; content:"action_code_who"; http_client_body; nocase; pcre:"/action_code_who[^\n]*%22[^\n]*%3C|action_code_who[^\n]*%22[^\n]*on[a-z]+=/i"; reference:cve,2026-91119; classtype:web-application-attack; sid:202691119; rev:1;)
Elastic Detection
sequence by user.name with maxspan=5m
[ network where network.protocol == "http" and http.request.method == "POST"
and http.request.body.text =~ """.*action_code_who.*""" ]
[ network where network.protocol == "http"
and http.request.body.text =~ """.*action_code_who.*("|%22).*(<|%3C|on[a-z]+=).*""" ]
Splunk SPL Query
index=web sourcetype=access_combined OR sourcetype=discourse
| eval suspicious=if(match(_raw, "(?i)action_code_who") AND match(_raw, "(%22|\\\")[^\\s]*(%3C|<|on[a-z]+%3D|on[a-z]+=)"), 1, 0)
| where suspicious=1
| stats count min(_time) as first_seen max(_time) as last_seen values(uri) as request_uris values(src_ip) as src_ips by user, host
| sort - count
Wazuh OSSEC Rule
<group name="web,discourse,cve-2026-91119,">
<rule id="100119" level="10">
<decoded_as>json</decoded_as>
<field name="url">action_code_who</field>
<regex type="pcre2">(?i)action_code_who.*(%22|")[^\s]*(%3C|<|on[a-z]+=)</regex>
<description>CVE-2026-91119: Possible Discourse HTML injection via action_code_who</description>
<mitre>
<id>T1059</id>
</mitre>
<group>cve_2026_91119,web_attack,</group>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source).
The vendor description references fixed versions (2026.1.8, 2026.6.3, 2026.7.2, and 2026.8.0), but no tracked patch source was confirmed in the provided data, so upgrades should be validated against the vendor's own release notes.
Immediate mitigations
- Upgrade to the vendor's current release branch as soon as a fixed version is available and validated (per description: 2026.1.8 or later on the 2026.1 line; 2026.6.3 or later; 2026.7.2 or later; 2026.8.0 or later).
- Restrict authenticated user ability to set display/actor names to trusted roles where operationally feasible, reducing the PR:L attack surface.
- Apply a strict Content Security Policy to limit the impact of rendered injected markup on trusted pages.
- Audit existing topic actions and activity logs for values containing quotes followed by markup, and sanitize or remove suspicious stored content.
Patch / upgrade steps
- Identify current Discourse version, compare against the fixed set.
- Follow the vendor's documented upgrade procedure (backup, then upgrade to the nearest fixed release).
- Confirm the fix post-upgrade by verifying the affected component behavior and re-checking stored action/activity-log values.
Long-term hardening
- Ensure all user-influenced values rendered into HTML attribute contexts are encoded with an attribute-appropriate encoder (e.g., URL-encode path components inside
href), rather than relying on text-context escaping alone. - Add automated regression tests for attribute-context encoding in render components.
- Monitor vendor advisories and inventory versions to shorten exposure windows.
- Ensure all user-influenced values rendered into HTML attribute contexts are encoded with an attribute-appropriate encoder (e.g., URL-encode path components inside
References
- NVD — CVE-2026-91119: https://nvd.nist.gov/vuln/detail/CVE-2026-91119
- Discourse official releases / security notes: https://github.com/discourse/discourse/releases
- Discourse meta (community/security announcements): https://meta.discourse.org/
- CWE-79 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'): https://cwe.mitre.org/data/definitions/79.html
- CISA Known Exploited Vulnerabilities Catalog (CVE not listed as of this report): https://www.cisa.gov/known-exploited-vulnerabilities-catalog
No known threat actor campaigns or exploit-in-the-wild evidence were provided; CISA KEV status is NO and no public PoC/exploit code exists in the available data.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.