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.
# 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.
# 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.

