☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
Discourse logo [ WEBSITE ] [ VENDOR STATS ]
CVSS: 5.4 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N 🐛 CWE-20
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2026-91134

CVE-2026-91134 Vulnerability in Discourse
📅 PUBLISHED: 2026-09-24 00:00 UTC 🔄 UPDATED: 2026-10-11 22:59 UTC
[ PATCH UNDER REVIEW ↓ ] Remains UNDER REVIEW until an independent source confirms the fix
[ DEFENSE PATCH ↓ ]
💣 PoC: None
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.22%
👁️
0.22% probability
5.4× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
🥷 MITRE: T1190
👁️
MITRE ATT&CK Tactic - Describes the strategy hackers use to execute this attack.
Country: United States License: Open Source
VULNERABLE: version not auto-detected — verify your deployed version locally
CVSS VECTOR BREAKDOWN 5.4
AV: N Attack Vector Network
AC: L Attack Complexity Low
PR: L Privileges Required Low
UI: N User Interaction None
S: U Scope Unchanged
C: L Confidentiality Low
I: L Integrity Low
A: N Availability None
5.4
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2026-91134 is a stored cross-origin iframe sanitizer bypass in Discourse, the open-source discussion platform. An authenticated user with posting privileges can persist an iframe whose src contains encoded userinfo, causing the post sanitizer's allowed_iframes prefix policy to validate a decoded URL while the browser interprets an attacker-controlled host. Successful exploitation renders attacker-controlled cross-origin content inside forum posts, affecting confidentiality and integrity at Low severity (CVSS 5.4). The issue is fixed in 2026.1.8, 2026.6.3, 2026.7.2, and 2026.8.0; no public PoC or in-the-wild exploitation is currently known.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

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.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Technical Analysis

Discourse uses the allowed_iframes setting to restrict which external frames may be embedded in posts. Prior to the listed fix versions, the post sanitizer performed prefix validation against a decoded form of the iframe src, but stored (and thus browser-interpreted) the raw encoded form. When the src contains encoded userinfo, the two representations resolve to different origins: the sanitizer sees an allowed-prefix string, while the browser parses an alternate host supplied via the encoded userinfo component. The allowlist check and the actual origin rendered by the browser therefore diverge.

The flaw class is CWE-20 (Improper Input Validation), specifically a canonicalization/decoding mismatch. This is a classic security-relevant failure: validation on one representation and enforcement on another. The attack surface is any Discourse deployment with user-generated post content and cross-origin iframe embedding governed by allowed_iframes. The NVD description does not specify the exact sanitization routine, parsing library, or the precise string comparison logic, so those implementation details are not asserted here. No encoding, header, or browser-quirk specifics beyond "encoded userinfo in iframe src" are established by the source data.

Because the sanitizer and the browser disagree on the effective origin, the impact is limited to rendering attacker-chosen cross-origin content within a trusted post context; it is not a server-side code execution flaw. CVSS subscores C:L and I:L reflect the constrained cross-origin content injection, while A:N and the unchanged Scope (S:U) reflect no direct availability impact and no privilege boundary crossing beyond the rendered frame.

Exploitation Scenarios

No public PoC is available; the chain below is inferred from the vulnerability class (stored sanitizer canonicalization bypass) and the NVD description, without fabricating implementation specifics.

  1. Reconnaissance/target identification: An attacker identifies a Discourse instance running a version prior to the fix releases, and determines whether cross-origin iframe embedding is permitted via the allowed_iframes policy. Authentication is required — the attacker needs an account with posting privileges (PR:L).

  2. Triggering the flaw class: The attacker composes a post containing an iframe whose src includes encoded userinfo, crafted so that the sanitizer's decoded prefix check matches an allowed entry while the browser resolves an attacker-controlled host.

  3. Payload/execution method: The payload is persisted as post content. On render, the sanitizer dependency accepts the decoded URL as an allowed prefix, but the browser interprets the encoded userinfo and loads the attacker-controlled cross-origin frame. The frame content is delivered from the attacker's host.

  4. Post-exploitation impact: Rendered cross-origin content appears within the trusted forum context. This can support content spoofing, phishing scaffolding, or embedding of attacker-controlled external interfaces, with Low confidentiality and integrity impact. No public exploit code, Nuclei template, or in-the-wild campaign is documented.

Impact Assessment

Business impact centers on trust and content integrity within hosted community platforms. Because the injected frame is cross-origin and controlled by the attacker, users may be exposed to misleading or malicious embedded content presented as part of the forum. CVSS 5.4 (AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N) indicates a moderately scored, network-reachable issue requiring low privileges, no user interaction, and no scope change. Blast radius is bounded to readability of rendered posts and potential secondary phishing, not to server compromise. Affected systems are Discourse deployments below the fixed versions, particularly those with cross-origin iframe embedding enabled and open registration or broad posting rights.

Detection Guidance

Sigma Rule

title: Discourse Post Stored Cross-Origin Iframe Sanitizer Bypass Attempt
id: 8f1c2d34-9b7e-4a1f-9d21-7c0e5f9a1b23
status: experimental
description: Detects post content containing iframe src values with encoded userinfo, consistent with CVE-2026-91134 sanitizer bypass.
logsource:
  product: discourse
  service: web
detection:
  selection_body:
    body|contains:
      - '<iframe'
  selection_userinfo:
    body|re:
      - '(?i)<iframe[^>]+src\s*=\s*["'']?[a-z]+://[^/?#@]+%40'
      - '(?i)<iframe[^>]+src\s*=\s*["'']?[a-z]+://[^/?#@]+%3A[^/?#@]*%40'
  condition: selection_body and selection_userinfo
falsepositives:
  - Legitimate iframe embeds from allowlisted domains containing encoded characters
level: medium
tags:
  - attack.t1190
  - cve.2026-91134

YARA Rule

rule CVE_2026_91134_Discourse_Iframe_Userinfo_Bypass
{
    meta:
        description = "Detects iframe src with encoded userinfo targeting Discourse allowed_iframes bypass (CVE-2026-91134)"
        author = "valtersit.com"
        date = "2026-01-01"
        reference = "CVE-2026-91134"
        severity = "medium"
    strings:
        $iframe = "<iframe" nocase
        $src1 = "src=" nocase
        $u1 = "%40" nocase
        $u2 = "%2540" nocase
        $u3 = "%3a" nocase
    condition:
        $iframe and $src1 and any of ($u*)
}

Suricata IDS Rule

alert http any any -> any any (msg:"CVE-2026-91134 Discourse Stored Iframe Userinfo Sanitizer Bypass"; flow:established,to_server; http.method; content:"POST"; http.request_body; content:"<iframe"; nocase; http.request_body; content:"src"; nocase; http.request_body; content:"%40"; nocase; reference:cve,2026-91134; classtype:web-application-attack; sid:202691134; rev:1;)

Elastic Detection

sequence by user.name with maxspan=5m
  [http where http.request.method == "POST" and http.request.body contains "<iframe"]
  [http where http.request.body contains "<iframe" and (http.request.body contains "%40" or http.request.body contains "%3A" or http.request.body contains "%2540")]

Splunk SPL Query

index=web sourcetype=access_combined_or_json
| search (uri_path="*/posts*" OR uri_path="*/posts.json*" OR uri_path="*/post*")
| search request_body="*<iframe*" AND (request_body="*%40*" OR request_body="*%3A*" OR request_body="*%2540*")
| stats count min(_time) as first_seen max(_time) as last_seen by src_ip, uri_path, user
| where count > 0
| convert ctime(first_seen) ctime(last_seen)

Wazuh OSSEC Rule

<group name="discourse,cve-2026-91134,">
  <rule id="202691134" level="8">
    <decoded_as>json</decoded_as>
    <field name="request_body">\.*<iframe\.*</field>
    <field name="request_body">\.*(%40|%3A|%2540)\.*</field>
    <description>CVE-2026-91134: Discourse post may contain cross-origin iframe with encoded userinfo sanitizer bypass.</description>
    <mitre>
      <id>T1190</id>
    </mitre>
    <group>web_application_attack,pci_dss_6.5,</group>
  </rule>
</group>

Mitigation & Patch Guidance

Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source).

  1. Immediate mitigations: Upgrade to a fixed release (2026.1.8, 2026.6.3, 2026.7.2, or 2026.8.0). Until then, tighten the allowed_iframes policy (restrict or disable cross-origin embedding), reduce posting privileges for untrusted users, and add content filters that flag <iframe bodies containing encoded userinfo (%40, %3A, or double-encoded variants). Apply WAF/pre-render filtering to inspect raw encoded src values rather than decoded representations.

  2. Patch/upgrade steps: Deploy the fixed version for your release track, restart Discourse, and re-validate that allowed_iframes behaves as intended post-upgrade. No vendor patch artifacts were tracked at the time of analysis, so verify the fix directly against the release notes for the version in use.

  3. Long-term hardening: Perform canonicalization consistently — validate the exact representation that will be interpreted downstream — and add regression tests for encoded userinfo/authority parsing in sanitizer pipelines. Adhere to an allowlist (never denylist) for embeddable origins, monitor for sanitizer/parser divergence in trusted-content rendering paths, and keep Discourse on supported tracks.

References

👁️ SHODAN DORKS (THREAT HUNTING)

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.

product:"Discourse"
title:"Discourse"
◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2026-91134/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.