CVE-2026-72729
Executive Summary
CVE-2026-72729 is a cross-site scripting (XSS) vulnerability in the discourse-local-dates plugin of Discourse, an open-source discussion platform. Discourse versions prior to 2026.1.6, 2026.5.2, 2026.6.1, and 2026.7.0 are affected; the plugin renders crafted local-date format data as HTML, which becomes exploitable on sites that have modified or disabled the default Content Security Policy (CSP). Successful exploitation allows an attacker to execute arbitrary script in the browser context of a victim viewing attacker-controlled content, with impact ranging from session hijacking to full account takeover.
Technical detail in the public advisory is limited to the NVD description; no CVSS score, no vendor advisory, and no public exploit code are available at this time. Exploitation probability is currently assessed as low (EPSS 0.00278, 20.3rd percentile).
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
The vulnerability resides in the conditional rendering path of the discourse-local-dates plugin. The plugin is responsible for localizing date and time values displayed within Discourse topics and posts. According to the NVD description, the plugin "rendered crafted local-date format data as HTML" prior to the fixed releases. This indicates that the plugin failed to sanitize or escape user-influenced date-format strings before inserting them into the Document Object Model (DOM) of a rendered page.
The key mitigating control for this flaw is the default Discourse Content Security Policy. A default, unmodified CSP would restrict the execution of inline scripts and unsafe HTML constructs, rendering the bug inert or limiting its impact. However, on sites where the administrator has deliberately modified or disabled the default CSP — a common operational decision on hosted Discourse communities to accommodate third-party widgets, custom analytics, or embedded media — the unsanitized output is rendered as active HTML and executes.
From a code-level perspective, the flaw is consistent with an improper neutralization of input during web page generation (CWE-79). The attack surface is the plugin's parsing/formatting pipeline, which consumes date-format data embedded in post content. Because the data flows from user-controlled content into a DOM sink, the vulnerability is likely triggerable by any user with permission to create or edit posts — including low-privilege or unauthenticated users depending on the instance's category and post permissions.
It must be emphasized that the NVD description does not expose function names, class names, URL endpoints, or parameter names. The precise internal API surface of the plugin, the exact markup syntax used to inject the crafted format data, and the specific rendering sink are not available from public data. The mechanism described above is inferred from the vulnerability class (CWE-79) and the behavior explicitly stated in the description ("rendered crafted local-date format data as HTML" under a weakened CSP). No public proof-of-concept or exploit code has been identified (PoC status: Unknown). The OSV entry lists the package with multiple commit revisions marked as unfixed, further indicating that the fix is version-gated rather than applied to all historical commits.
Exploitation Scenarios
The attack chain for CVE-2026-72729 is reconstructed at the vulnerability-class level because no public PoC exists. The chain proceeds as follows:
Step 1 — Reconnaissance and target identification. The attacker identifies Discourse instances running affected versions (prior to 2026.1.6, 2026.5.2, 2026.6.1, and 2026.7.0). Instance fingerprinting is straightforward via standard web reconnaissance: Discourse version metadata is frequently visible in HTML meta tags, HTTP headers, and static asset paths. The attacker then probes whether the instance enforces a strict default CSP by inspecting Content-Security-Policy response headers on page loads. Instances with a modified, permissive, or absent CSP are prioritized because they are the only environments where the HTML-rendered payload will execute.
Step 2 — Triggering the flawed rendering path. The attacker crafts a post, comment, or other user-editable content element that embeds a malicious local-date format string. The discourse-local-dates plugin parses this format data during the client-side rendering of the forum thread. Because the input is not neutralized, the format value is inserted into the DOM as raw HTML rather than as inert text. The attacker does not need to bypass server-side filters if those filters do not validate this specific plugin's format-data channel; the vulnerability is in the rendering logic, not in initial input acceptance.
Step 3 — Payload execution (vulnerability-class mechanics). The payload carried in the crafted local-date format data is delivered as HTML — for example, markup that introduces a <script> element or an inline event handler. On a default-configuration Discourse instance, the CSP would block this execution. On an instance with a weakened/disabled CSP, the injected markup executes in the victim's browser session the moment the victim views the thread. Because the victim is typically an authenticated user, the script runs with the victim's session cookies and CSRF tokens, within the origin of the vulnerable Discourse domain.
Step 4 — Post-exploitation impact. With arbitrary script execution in the victim's browser context, the attacker can:
- Read and exfiltrate the victim's personal data (email, profile fields, private messages rendered in the page).
- Perform actions on behalf of the victim, including posting content, changing profile settings, or — if the victim is an administrator — modifying site configuration, granting privileges, or installing malicious theme components.
- Establish persistence via stored XSS that re-triggers for every subsequent visitor to the poisoned content.
- Pivot to a broader drive-by compromise scenario by redirecting victims to credential-harvesting pages.
It is acceptable and recommended to treat this attack chain as inferred from CWE-79 and the NVD description; the absence of a public PoC means specific payload syntax and exact plugin markup remain unverified.
Impact Assessment
Business impact. For an open-source discussion platform, trust is the primary asset. An XSS vulnerability that executes in the context of authenticated forum users undermines the confidentiality and integrity of user communications, private messages, and moderator/admin accounts. A successful campaign against an enterprise Discourse deployment could result in account takeover of privileged users, unauthorized content manipulation (including the planting of further malicious content), and reputational damage.
Affected systems. All Discourse installations running versions prior to 2026.1.6, 2026.5.2, 2026.6.1, and 2026.7.0 that use the discourse-local-dates plugin and enforce a non-default (modified or disabled) Content Security Policy. Instances running the default CSP are significantly less exposed because the CSP blocks execution of the rendered HTML.
Blast radius. The stored nature of the flaw (content-based trigger) means a single malicious post can affect every user who views it, amplifying the blast radius across the entire user base. The conditional CSP dependency narrows actual exposure but expands the risk for administrators who have loosened CSP for operational convenience.
Severity context. CVSS data is N/A — no vector or base score has been published. The EPSS score of 0.00278 (20.3rd percentile) suggests a low near-term probability of exploitation in the wild. CISA KEV does not list this CVE, and no threat-actor campaigns have been publicly attributed. However, the absence of a CVSS score is not an indicator of low severity; it reflects incomplete vendor/CNA scoring at the time of this report. SOC teams should treat this as a high-priority patching item given the clarity of the fix versions and the known XSS class.
Detection Guidance
Detection of this vulnerability is challenging because the malicious payload is rendered client-side and the server-side request may appear as a benign post submission. The rules below focus on three observable layers: (1) web requests carrying XSS indicators toward Discourse plugin-related endpoints, (2) response content containing HTML-rendered date-format payloads, and (3) downstream browser-side events such as CSP violation reports. The plugin name discourse-local-dates is used verbatim from the NVD description.
Sigma Rule
title: CVE-2026-72729 Discourse local-dates XSS Payload in Web Request
id: 7a3b9f6c-2c41-4f9a-bc31-1e6f8a2d5c90
status: experimental
description: >
Detects HTTP requests to Discourse instances that reference the
discourse-local-dates plugin while containing common XSS payload
markers in the URL query string or request body. Aligns with the
crafted local-date format data rendering as HTML (CVE-2026-72729).
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-72729
author: Valters IT Threat Intelligence
date: 2026/02/18
logsource:
category: webserver
product: apache
definition: 'Requests to a Discourse installation web server'
detection:
selection_plugin_ref:
- cs-uri-path|contains: 'discourse-local-dates'
- cs-uri-query|contains: 'discourse-local-dates'
selection_xss_markers:
- cs-uri-query|contains:
- '<script'
- '%3Cscript'
- 'javascript:'
- 'onerror='
- 'onload='
- 'data:text/html'
- cs-uri-query|contains|winded: 'local'
condition: selection_plugin_ref and selection_xss_markers
falsepositives:
- Legitimate date-format customization strings containing the word "local"
- Security scanners probing for XSS
level: high
tags:
- attack.t1189
- cwe.79
- cve.2026.72729
YARA Rule
rule CVE_2026_72729_Discourse_Local_Dates_XSS
{
meta:
author = "Valters IT Threat Intelligence"
description = "Detects stored content or HTML responses combining discourse-local-dates plugin references with script injection markers (CWE-79)"
cve = "CVE-2026-72729"
date = "2026-02-18"
severity = "high"
strings:
$plugin_ref = "discourse-local-dates" ascii nocase
$script_inline = "<script" ascii nocase
$script_encoded = "%3Cscript" ascii nocase
$event_handler = /on(error|load|click|mouseover)\s*=/ ascii nocase
$javascript_uri = "javascript:" ascii nocase
$svg_onload = "<svg/onload=" ascii nocase
$iframe_data = "data:text/html" ascii nocase
condition:
$plugin_ref and 1 of ($script_inline, $script_encoded, $event_handler, $javascript_uri, $svg_onload, $iframe_data)
}
Suricata IDS Rule
alert http any any -> $HOME_NET any \
(msg:"CVE-2026-72729 Discourse discourse-local-dates XSS attempt"; \
flow:established,to_server; \
http.uri; content:"discourse-local-dates"; nocase; \
http.uri; content:"<script"; nocase; \
http.request_body; content:"discourse-local-dates"; nocase; \
http.request_body; content:"onerror"; nocase; \
sid:7292901; rev:1; \
reference:cve,2026-72729; reference:url,https://nvd.nist.gov/vuln/detail/CVE-2026-72729; \
classtype:web-application-attack; priority:1;)
The rule alerts when a request URI references the plugin and contains a raw <script marker, or when the request body carries both a plugin reference and an event-handler keyword. Tune $HOME_NET to the Discourse server subnet, and expect false positives from automated XSS scanners.
Elastic Detection
sequence by source.ip with maxspan=30s
[ network where
network.protocol == "http" and
http.request.method in ("GET", "POST") and
(wildcard(http.request.uri, "*discourse-local-dates*") or
wildcard(http.request.body.content, "*discourse-local-dates*")) and
(wildcard(http.request.body.content, "*<script*") or
wildcard(http.request.uri, "*%3Cscript*") or
wildcard(http.request.body.content, "*javascript:*") or
wildcard(http.request.body.content, "*onerror=*"))
]
[ http where
http.response.status_code == 200 and
(wildcard(http.response.body.content, "*discourse-local-dates*") or
wildcard(http.response.body.content, "*<script*"))
]
This EQL rule pairs an inbound request carrying XSS markers and plugin references with a subsequent 200 response returning plugin or script content to the same source IP — a pattern consistent with a victim loading poisoned forum content.
Splunk SPL Query
index=web sourcetype=access_combined OR sourcetype=iis
| where (like(uri_path, "%discourse-local-dates%") OR like(uri, "%discourse-local-dates%"))
AND (like(uri_query, "%<script%") OR like(uri_query, "%3Cscript%")
OR like(uri_query, "%javascript:%") OR like(uri_query, "%onerror=%")
OR like(uri_query, "%onload=%") OR like(uri_query, "%data:text/html%"))
| eval threat=case(
like(uri_query, "%<script%") OR like(uri_query, "%3Cscript%"), "inline_script",
like(uri_query, "%javascript:%"), "javascript_uri",
like(uri_query, "%onerror=%") OR like(uri_query, "%onload=%"), "event_handler",
like(uri_query, "%data:text/html%"), "data_uri",
1=1, "unknown")
| stats count by src_ip, dest_ip, uri, status, threat, user_agent, _time
| sort - _time
| where count >= 1
The query surfaces web requests referencing the vulnerable plugin path plus any common XSS marker, with a threat field summarizing the payload flavor. Add a threshold over repeated hits from a single src_ip to suppress single-scan false positives.
Wazuh OSSEC Rule
<group name="web,xss,cve_2026_72729,">
<rule id="102729" level="12" frequency="4" timeframe="120">
<decoded_as>web</decoded_as>
<match>discourse-local-dates</match>
<regex>(\<script|%3Cscript|javascript:|on(error|load|mouseover)[[:space:]]*=)</regex>
<description>CVE-2026-72729: Possible XSS payload targeting the Discourse discourse-local-dates plugin</description>
<mitre>
<id>T1189</id>
</mitre>
<group>attack.t1189,cwe.79,</group>
</rule>
</group>
This OSSEC rule triggers when a decoded web log line references discourse-local-dates combined with script or event-handler injection markers, using a frequency threshold of 4 hits in 120 seconds to reduce noise. Adjust frequency and timeframe based on observed site traffic and scanner activity.
Mitigation & Patch Guidance
Patch confidence for CVE-2026-72729 is 2/4 (CLAIMED): the fix is reported by a single source (OSV), and has not been independently confirmed via a vendor security advisory at the time of writing.
1) Immediate mitigations.
- Re-enforce the default Discourse Content Security Policy. Verify that
Content-Security-Policyresponse headers are present and strict (blocking inline scripts and unsafe-eval). Sites that intentionally modified or disabled the CSP are the only known-exploitable configurations and should be restored to the default policy immediately. - If the CSP cannot be restored promptly, disable the
discourse-local-datesplugin on production instances until the upgrade is completed. - Restrict posting privileges to trusted users in forums where the plugin is active, and temporarily moderate posts containing local-date markup.
2) Patch and upgrade steps.
- Upgrade Discourse to the appropriate fixed release for your branch: 2026.1.6, 2026.5.2, 2026.6.1, or 2026.7.0.
- Before deploying in production, verify the fix independently: confirm the release notes or vendor advisory mention CVE-2026-72729, and smoke-test the local-dates functionality on a staging instance after upgrade.
- Note that the OSV package entry lists several commit revisions as unfixed; ensure the deployed build is the released fixed version, not merely a recent commit.
3) Long-term hardening.
- Establish a policy that default security controls (CSP, headers, cookie flags) are never weakened without a compensating control and a documented risk acceptance.
- Enable CSP reporting (
report-uri/report-to) to receive browser-side violation telemetry that can indicate XSS attempts, and forward those reports to the SIEM. - Subscribe to Discourse security advisories and OSV feeds for prompt awareness of future plugin-related vulnerabilities.
- Audit Discourse plugin inventory quarterly; remove or replace plugins that are unmaintained or that regularly expand the attack surface.
References
- NVD entry: https://nvd.nist.gov/vuln/detail/CVE-2026-72729
- OSV vulnerability entry (patch source): https://osv.dev/vulnerability/CVE-2026-72729
- CWE-79 (Improper Neutralization of Input During Web Page Generation): https://cwe.mitre.org/data/definitions/79.html
- Discourse official project site: https://www.discourse.org/
- CISA Known Exploited Vulnerabilities catalog (no entry for CVE-2026-72729 as of 2026-02-18): https://www.cisa.gov/known-exploited-vulnerabilities-catalog
No public exploit code, Nuclei template, or YARA/signature from third-party vendors is currently available. No threat actor campaigns exploiting CVE-2026-72729 in the wild have been reported; the CISA KEV catalog does not list this CVE, and the EPSS score (0.00278) indicates low near-term exploitation likelihood. Analysts should monitor the OSV entry and Discourse release channels for an independent confirmation of the patch and any amendment to the advisory detail.
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.