CVE-2026-41591 Overview
CVE-2026-41591 is a cross-site scripting (XSS) vulnerability in Marko, a declarative HTML-based language for building web applications. The flaw affects marko versions prior to 5.38.36 and @marko/runtime-tags versions prior to 6.0.164. The Marko runtime failed to prevent tag breakout when closing <script> or <style> tags used non-lowercase casing. Attackers who control input rendered inside these tags can escape the element using sequences like </SCRIPT> or </Style> and inject arbitrary HTML or JavaScript. The vulnerability is tracked under [CWE-79] (Improper Neutralization of Input During Web Page Generation).
Critical Impact
Attackers with the ability to influence dynamic text inside <script> or <style> blocks can inject arbitrary JavaScript, leading to session theft, account takeover, and client-side code execution.
Affected Products
- marko versions prior to 5.38.36
- @marko/runtime-tags versions prior to 6.0.164
- Web applications built on the Marko framework that interpolate untrusted data inside <script> or <style> tags
Discovery Timeline
- 2026-05-08 - CVE-2026-41591 published to NVD
- 2026-05-13 - Last updated in NVD database
Technical Details for CVE-2026-41591
Vulnerability Analysis
Marko compiles templates that allow dynamic data interpolation inside HTML elements, including <script> and <style> blocks. The runtime applies context-aware escaping to neutralize closing tag sequences and prevent attackers from terminating the element early. The escaping logic checked for lowercase variants such as </script> and </style> but did not normalize casing before matching. As a result, mixed-case or uppercase closing tags including </SCRIPT>, </Script>, and </Style> passed through unmodified.
HTML parsers in browsers treat tag names as case-insensitive. A payload containing </SCRIPT><img src=x onerror=alert(1)> terminates the script element and injects new DOM nodes. This produces a stored or reflected XSS condition depending on how the application sources the tainted input. The issue is scoped to dynamic text expressions rendered inside <script> or <style> tags, which are common locations for serializing server state to the client.
Root Cause
The root cause is incomplete output encoding in Marko's special-tag escaper. The escape function compared substrings against lowercase literals without applying a case-insensitive match or normalizing the input. Any closing tag using uppercase characters bypassed the sanitizer and reached the rendered HTML unchanged.
Attack Vector
An attacker supplies input that flows into a <script> or <style> tag via a Marko template expression. The payload includes a mixed-case closing tag followed by attacker-controlled markup. When the page renders, the browser closes the script or style element and parses the injected HTML, executing any embedded JavaScript in the victim's session context. Exploitation requires the application to render untrusted data inside one of these tags, which is typical for inlined configuration objects and theme variables.
No verified public proof-of-concept code is available. See the GitHub Security Advisory for additional technical context.
Detection Methods for CVE-2026-41591
Indicators of Compromise
- HTTP request bodies or query parameters containing mixed-case closing tag sequences such as </SCRIPT>, </Script>, or </Style>
- Unexpected outbound requests from browser sessions to attacker-controlled domains following page loads
- Rendered HTML responses where dynamic Marko template output contains uppercase closing tags adjacent to injected markup
Detection Strategies
- Inspect server access logs for request parameters containing closing tag patterns with non-lowercase characters
- Apply static analysis to Marko templates to identify dynamic expressions placed inside <script> or <style> blocks
- Deploy Content Security Policy (CSP) violation reporting to surface unexpected script execution on production pages
Monitoring Recommendations
- Monitor web application firewall (WAF) logs for XSS payload signatures using case-variant tag breakout patterns
- Track JavaScript error telemetry and CSP reports for anomalies that correlate with user-supplied input fields
- Audit dependency manifests across build pipelines to detect Marko versions below the patched releases
How to Mitigate CVE-2026-41591
Immediate Actions Required
- Upgrade marko to version 5.38.36 or later and @marko/runtime-tags to version 6.0.164 or later
- Audit Marko templates for dynamic expressions inside <script> and <style> tags and validate input sources
- Deploy a strict Content Security Policy to limit the impact of any residual XSS exposure
Patch Information
The Marko maintainers fixed the vulnerability in marko 5.38.36 and @marko/runtime-tags 6.0.164. The patch updates the special-tag escaping logic to perform case-insensitive matching against closing tag sequences. Details are published in the GitHub Security Advisory GHSA-x9fj-57fh-c8wq.
Workarounds
- Avoid interpolating untrusted data directly inside <script> or <style> tags; pass values through data-* attributes and read them with JavaScript instead
- Pre-sanitize input on the server to reject or encode any substring matching closing tag patterns regardless of case
- Apply a CSP script-src directive that disallows inline scripts and requires nonces or hashes for legitimate script blocks
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

