Severity by source
AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N
Low-privilege authenticated attacker posts crafted content; injection propagates to email recipients outside Discourse scope yielding S:C, with low C/I and no availability impact.
Primary rating from Vendor (GitHub_M).
CVSS VectorVendor: GitHub_M
Lifecycle Timeline
4DescriptionCVE.org
Discourse is an open-source discussion platform. Prior to 2026.1.7, 2026.6.2, 2026.7.1, and 2026.8.0-latest.1, Discourse has HTML injection in PrettyText.format_for_email because cooked attribute values are reparsed as markup. Crafted Vimeo iframe sources, secure-upload URLs or dimensions, and hashtag data-slug values can cause decoded attribute text to be reinterpreted as HTML. The vulnerable conversion also fails to strictly validate the Vimeo iframe host and path, allowing non-Vimeo allowlisted iframes to be converted. This issue is fixed in versions 2026.1.7, 2026.6.2, 2026.7.1, and 2026.8.0-latest.1.
AnalysisAI
HTML injection in Discourse's PrettyText.format_for_email function allows authenticated users to embed arbitrary markup into outbound email notifications across all versions prior to 2026.1.7, 2026.6.2, 2026.7.1, and 2026.8.0-latest.1. Three distinct code paths in the email conversion pipeline re-inject cooked HTML attribute values as raw markup strings rather than treating them as data - exploitable via crafted Vimeo iframe sources, secure-upload URLs or dimension attributes, and hashtag data-slug values. No public exploit code or CISA KEV listing is identified at time of analysis; the CVSS 3.1 score of 6.4 reflects a meaningful scope change to email recipients' clients combined with the low-privilege authentication requirement.
Technical ContextAI
Discourse's Ruby-based PrettyText module converts stored Nokogiri-parsed HTML ('cooked' posts) into email-safe markup via format_for_email. The root cause maps to CWE-79 (Improper Neutralization of Input During Web Page Generation): three independent code paths interpolate attribute values directly into HTML strings rather than using Nokogiri's DOM API. First, hashtag data-slug attributes were passed through hashtag.replace() as a raw interpolated string, allowing injected tag payloads in slug values. Second, convert_vimeo_iframes used Nokogiri::HTML5.fragment() with unsanitized string interpolation and did not enforce that the iframe src host matched player.vimeo.com or that the path matched a /video/<id> pattern - letting non-Vimeo, allowlist-bypassing iframes generate injected HTML output. Third, the strip_secure_uploads path constructed its notice div via a heredoc string, embedding URL and numeric dimension attributes without sanitization. The onebox origin regex was also insufficiently anchored, permitting host-prefix bypass. All four fixes in PRs 42244-42247 replace string interpolation with DOM construction methods (create_element, create_text_node, add_child), strictly validate Vimeo host and path against compiled constants, and tighten origin boundary anchoring. Affected CPE: cpe:2.3:a:discourse:discourse:*:*:*:*:*:*:*:*.
RemediationAI
Upgrade Discourse to a patched release immediately: 2026.1.7 for the stable-1.x branch, 2026.6.2 for the June stable track, 2026.7.1 for the July stable track, or 2026.8.0-latest.1 for the beta/latest track. All four fixes are documented in GitHub Security Advisory GHSA-3q6f-6gm9-m35v and merged via pull requests 42244, 42245, 42246, and 42247 in the discourse/discourse repository. If an immediate upgrade is not operationally feasible, the most effective compensating control is to disable outbound email notifications entirely via Admin > Email settings, which prevents the vulnerable format_for_email code path from executing - though this eliminates all digest and topic notification emails, which may be unacceptable operationally. Restricting membership to trusted users (disabling open registration and raising the minimum trust level required for posting) reduces the attacker pool but does not eliminate the vulnerability if any member account could be compromised or is malicious. Disabling Vimeo onebox embedding or the secure-upload feature individually would close those specific attack vectors but does not address the hashtag slug injection path. No single configuration toggle eliminates all three vectors without patch.
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
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
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
Discourse is an open source platform for community discussion. Rated critical severity (CVSS 9.8), this vulnerability is
Unauthorized access to hidden post revisions in Discourse through version enumeration allows unauthenticated users to by
Same weakness CWE-79 – Cross-site Scripting (XSS)
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-55656