Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-46628

CVE-2026-46628: Symfony Twig XSS Vulnerability

CVE-2026-46628 is a cross-site scripting flaw in Symfony Twig affecting the spaceless filter before version 3.26.0. Attackers can inject malicious code through unescaped markup. This article covers technical details, affected versions, impact, and mitigation steps.

Published:

CVE-2026-46628 Overview

CVE-2026-46628 affects Twig, a widely deployed template language for PHP maintained by the Symfony ecosystem. The deprecated spaceless filter is registered as safe for HTML, which causes Twig's autoescaper to emit attacker-controlled markup without escaping. When the filter is applied to untrusted input, the output bypasses HTML autoescaping and enables cross-site scripting (XSS). The issue is fixed in Twig version 3.26.0, which pre-escapes HTML input on the spaceless filter. This flaw is classified under [CWE-116: Improper Encoding or Escaping of Output].

Critical Impact

Applications passing untrusted input through the spaceless filter render attacker-controlled HTML unescaped, exposing users to cross-site scripting in an otherwise autoescaped Twig template.

Affected Products

  • Symfony Twig versions prior to 3.26.0
  • PHP applications using the deprecated spaceless filter on untrusted input
  • Custom filters declared with 'is_safe' => ['html'] but without 'pre_escape' => 'html'

Discovery Timeline

  • 2026-07-14 - CVE-2026-46628 published to NVD
  • 2026-07-16 - Last updated in NVD database

Technical Details for CVE-2026-46628

Vulnerability Analysis

Twig autoescaping normally HTML-encodes any variable rendered in an HTML context. Filters can override this behavior by declaring themselves safe for a given context using 'is_safe' => ['html']. Declaring a filter safe tells the compiler that the filter's output is trusted HTML and should not be escaped again.

The deprecated spaceless filter was registered as safe for HTML but did not pre-escape its input. As a result, if a template applied spaceless to a user-controlled string, the raw input passed through the filter and was emitted verbatim to the browser. This effectively made {{ user_input|spaceless }} equivalent to {{ user_input|raw }} in an HTML context, defeating Twig's default protection against XSS.

Root Cause

The root cause is a mismatch between the is_safe declaration and the absence of a pre_escape declaration on the spaceless filter. In Twig's filter API, is_safe suppresses autoescaping on filter output, while pre_escape instructs the compiler to escape the input before it reaches the filter. Declaring only is_safe without pre_escape treats untrusted input as pre-sanitized HTML.

Attack Vector

Exploitation requires an application to pass attacker-controlled input through the spaceless filter in an HTML-rendered Twig template. An attacker submits input containing HTML or JavaScript payloads through any request field ultimately rendered with {{ input|spaceless }}. Because the output is treated as safe HTML, the payload executes in the victim's browser under the application's origin. User interaction, such as visiting the rendered page, is required.

text
# 3.26.0 (2026-XX-XX)

+ * Pre-escape HTML input on the `spaceless` filter
  * Encode single quotes as `\\x27` in `Compiler::string()` as a defense-in-depth measure
  * Fix sandbox `__toString` bypasses
  * Add `Twig\Node\CoercesChildrenToStringInterface` to let nodes declare which of their child nodes will be string-coerced at runtime so the sandbox wraps them with a `__toString` check

Source: Twig CHANGELOG commit 3190b9a. The patch adds pre_escape to the spaceless filter so the autoescaper HTML-encodes untrusted input before the filter processes it.

Detection Methods for CVE-2026-46628

Indicators of Compromise

  • Web server access logs containing HTML or JavaScript payload characters (<script>, onerror=, javascript:) in query parameters or form fields that map to templates using spaceless.
  • Content Security Policy (CSP) violation reports referencing inline script execution on pages rendered through Twig.
  • Unexpected outbound requests from user browsers to attacker-controlled domains after visiting application pages.

Detection Strategies

  • Grep the Twig template codebase for the |spaceless filter usage: grep -r "|\s*spaceless" templates/.
  • Audit any custom filter registrations that declare 'is_safe' => ['html'] without a corresponding 'pre_escape' => 'html' option.
  • Inspect installed Twig package versions with composer show twig/twig and flag any version below 3.26.0.

Monitoring Recommendations

  • Deploy a web application firewall (WAF) rule set that flags HTML tag and event-handler patterns in request parameters targeting affected endpoints.
  • Enable CSP with report-uri or report-to directives to surface unexpected inline script execution in production.
  • Monitor application error logs and dependency scanning tools for advisories referencing GHSA-4j38-f5cw-54h7.

How to Mitigate CVE-2026-46628

Immediate Actions Required

  • Upgrade Twig to version 3.26.0 or later using composer require twig/twig:^3.26.0.
  • Identify all templates using the |spaceless filter and, where possible, replace them with the whitespace control features documented for Twig 3.12+.
  • Review any custom filters declared safe for HTML and add 'pre_escape' => 'html' where user input can flow through them.

Patch Information

The fix is delivered in Twig 3.26.0 via commit 3190b9ae12614dfd58cc5d8f394bac4708b17913. The patch pre-escapes HTML input on the spaceless filter, encodes single quotes as \\x27 in Compiler::string() as defense-in-depth, and fixes sandbox __toString bypasses. Full release notes are available on the Twig v3.26.0 release page.

Workarounds

  • Remove |spaceless from any template that renders untrusted input until the upgrade is deployed.
  • Manually escape input before applying the filter: {{ user_input|e('html')|spaceless }}.
  • For applications that re-implement spaceless, declare the filter with both 'pre_escape' => 'html' and 'is_safe' => ['html'] as recommended in the updated Twig spaceless documentation.
bash
# Upgrade Twig to the patched release
composer require twig/twig:^3.26.0

# Verify the installed version
composer show twig/twig | grep versions

# Search codebase for vulnerable filter usage
grep -rn "|\s*spaceless" templates/ src/

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.