mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-13 10:56:38 +00:00
security #cve-2026-46628 Pre-escape HTML input on the spaceless filter (fabpot)
This PR was merged into the twig-3.x branch.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# 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
|
||||
|
||||
@@ -6,6 +6,16 @@
|
||||
The ``spaceless`` filter is deprecated as of Twig 3.12. While not a full
|
||||
replacement, you can check the :ref:`whitespace control features <templates-whitespace-control>`.
|
||||
|
||||
.. caution::
|
||||
|
||||
The ``spaceless`` filter is declared safe for the ``html`` context, so its
|
||||
output is not auto-escaped. Its input is therefore pre-escaped by the
|
||||
auto-escaper when needed. If you re-implement this filter in your own
|
||||
code, declare it with both ``'pre_escape' => 'html'`` and
|
||||
``'is_safe' => ['html']``: declaring ``is_safe`` without ``pre_escape``
|
||||
is equivalent to piping user input through ``|raw`` and opens an XSS
|
||||
vector.
|
||||
|
||||
Use the ``spaceless`` filter to remove whitespace *between HTML tags*, not
|
||||
whitespace within HTML tags or whitespace in plain text:
|
||||
|
||||
|
||||
@@ -258,7 +258,7 @@ final class CoreExtension extends AbstractExtension
|
||||
new TwigFilter('striptags', [self::class, 'striptags']),
|
||||
new TwigFilter('trim', [self::class, 'trim']),
|
||||
new TwigFilter('nl2br', [self::class, 'nl2br'], ['pre_escape' => 'html', 'is_safe' => ['html']]),
|
||||
new TwigFilter('spaceless', [self::class, 'spaceless'], ['is_safe' => ['html'], 'deprecation_info' => new DeprecatedCallableInfo('twig/twig', '3.12')]),
|
||||
new TwigFilter('spaceless', [self::class, 'spaceless'], ['pre_escape' => 'html', 'is_safe' => ['html'], 'deprecation_info' => new DeprecatedCallableInfo('twig/twig', '3.12')]),
|
||||
|
||||
// array helpers
|
||||
new TwigFilter('join', [self::class, 'join']),
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
"spaceless" filter pre-escapes its input under autoescape
|
||||
--DEPRECATION--
|
||||
Since twig/twig 3.12: Twig Filter "spaceless" is deprecated in index.twig at line 3.
|
||||
Since twig/twig 3.12: Twig Filter "spaceless" is deprecated in index.twig at line 5.
|
||||
Since twig/twig 3.12: Twig Filter "spaceless" is deprecated in index.twig at line 7.
|
||||
--TEMPLATE--
|
||||
{% autoescape 'html' %}
|
||||
1. {{ payload|spaceless }}
|
||||
|
||||
2. {{ payload|escape|spaceless }}
|
||||
|
||||
3. {{ payload|raw|spaceless }}
|
||||
{% endautoescape %}
|
||||
--DATA--
|
||||
return ['payload' => '<script> alert(1) </script>']
|
||||
--EXPECT--
|
||||
1. <script> alert(1) </script>
|
||||
|
||||
2. <script> alert(1) </script>
|
||||
|
||||
3. <script> alert(1) </script>
|
||||
Reference in New Issue
Block a user