CVE-2026-72720
This is not three independent input validation failures. It is one systemic bug manifesting through three distinct vectors—Vimeo iframe sources, secure-upload metadata, and hashtag data-slugs all trigger the same transformation failure through PrettyText.format_for_email. The root cause is a context-confusion vulnerability: attribute values are 'cooked' (sanitized for one rendering context) and then reparsed as markup in a different context. The function was designed to receive pre-sanitized HTML, but receives content whose attributes survive the initial cooking in a form that becomes dangerous when re-parsed. The multiplicity of vectors is analytically significant. When three unrelated code paths feed into a single transformation function and produce identical injection failures, the bug lives in the shared reparsing logic, not in the individual attribute generators. The non-Vimeo iframe bypass compounds this—it suggests host validation was patched onto one specific code path rather than enforced at the transformation boundary itself, a classic pattern where a security fix addresses a known vector without restructuring the underlying assumption that made the vector possible. The email rendering context makes this worse than the CVSS 6.4 suggests. Email is a transitive delivery mechanism where the attack surface compounds through forwarding chains. A payload embedded in a notification persists in inboxes, gets forwarded to colleagues outside the Discourse ecosystem, and lands in environments with entirely different security postures—unpatched mail clients, legacy gateways. The patch protects Discourse users but cannot protect downstream recipients. The practical implication: format_for_email needs a defensive entry-point transformation, not scattered caller validation. If this function is a security boundary receiving data from untrusted sources, its contract should enforce context-aware sanitization at intake rather than relying on callers to pre-sanitize for a context the function itself then re-parses unsafely. The fix ordering question—patching individual vectors versus restructuring the shared reparsing step—determines whether the vulnerability is truly closed or merely patched to the known surface. Expect a fourth vector within months if the patch only hardens current paths without treating format_for_email as a permanent security boundary with explicit input validation contracts.
Reviewed through automated stages and approved by a human before publication.