Commit Graph

7467 Commits

Author SHA1 Message Date
Fabien Potencier ed6df6b4b4 Fix deprecated PHP CS Fixer rules 2026-05-22 12:25:06 +02:00
Fabien Potencier a0a1f1d17d Replace FQCN with use statements in SandboxTest 2026-05-22 12:08:11 +02:00
Fabien Potencier 4a64b5b486 Fix CS 2026-05-21 16:34:23 +02:00
Fabien Potencier 91b3d5182d Bump version 2026-05-20 09:32:26 +02:00
Fabien Potencier 1fcae487b1 Prepare the 3.26.0 release v3.26.0 2026-05-20 09:31:59 +02:00
Fabien Potencier 40d4f8a4ab Update CHANGELOG 2026-05-20 09:23:11 +02:00
Fabien Potencier 116dae25bc security #cve-2026-46627 Document that the sandbox doesn't protect against resource exhaustion (fabpot)
This PR was merged into the twig-3.x branch.
2026-05-20 09:16:35 +02:00
Fabien Potencier 6bfa285e2f Document that the sandbox doesn't protect against resource exhaustion 2026-05-20 09:12:32 +02:00
Fabien Potencier 7923de168b security #cve-2026-46628 Pre-escape HTML input on the spaceless filter (fabpot)
This PR was merged into the twig-3.x branch.
2026-05-20 08:53:45 +02:00
Fabien Potencier 47ca88d78b security #cve-2026-46634 Document template_from_string caveats when used in a sandboxed env (fabpot)
This PR was merged into the twig-3.x branch.
2026-05-20 08:51:01 +02:00
Fabien Potencier 1cde8f2b62 Document template_from_string caveats when used in a sandboxed env 2026-05-20 08:43:49 +02:00
Fabien Potencier 3190b9ae12 Pre-escape HTML input on the spaceless filter 2026-05-20 08:29:48 +02:00
Fabien Potencier b9e6e654af Add docs on Markup about the goal of this class in the context of a sandbox 2026-05-20 08:14:13 +02:00
Fabien Potencier 673f02cb6d security #cve-2026-46635 Fix sandbox bypass in the "column" filter (alexandre-daubois)
This PR was merged into the twig-3.x branch.
2026-05-20 07:35:59 +02:00
Alexandre Daubois f05c5011c2 Fix sandbox bypass in the "column" filter 2026-05-20 07:33:52 +02:00
Fabien Potencier 2e4b6d286e security #cve-2026-47732 [Sandbox] Fix __toString() support (fabpot)
This PR was merged into the twig-3.x branch.
2026-05-20 07:31:34 +02:00
Fabien Potencier 3464990a51 security #cve-2026-47730 [Profiler] Escape template and profile names in HtmlDumper (nicolas-grekas)
This PR was merged into the twig-3.x branch.
2026-05-20 07:31:01 +02:00
Fabien Potencier 447d0b2331 Fix sandbox __toString bypasses 2026-05-20 00:18:59 +02:00
Fabien Potencier 7f3056a28e security #cve-2026-46640 Fix sandbox bypass: PHP code injection via _self / import macro reference (alexandre-daubois, fabpot)
This PR was merged into the twig-3.x branch.
2026-05-19 23:43:36 +02:00
Fabien Potencier ea3f7a2844 Validate macro name in MacroReferenceExpression constructor
The name passed to MacroReferenceExpression is emitted as raw PHP in
compile() via "->{$name}(...)". Callers were expected to validate
the name, but a missing check led to CVE-2026-XXXXX (PHP code injection
via _self / import macro reference): defense-in-depth, validate the
name in the constructor so the class is safe by construction.
2026-05-19 23:42:31 +02:00
Alexandre Daubois 324fa60545 Fix sandbox bypass: PHP code injection via _self / import macro reference 2026-05-19 23:41:59 +02:00
Fabien Potencier aeb37f4801 Fix deprecations in tests 2026-05-19 23:05:30 +02:00
Fabien Potencier 1a023fef43 security #cve-2026-46638 Fix sandbox bypass in the {% sandbox %} tag when including a preloaded template (alexandre-daubois)
This PR was merged into the twig-3.x branch.
2026-05-19 23:02:22 +02:00
Alexandre Daubois 819c6a89fe Fix sandbox bypass in the {% sandbox %} tag when including a preloaded template 2026-05-19 23:00:58 +02:00
Fabien Potencier ea7879a67f security #cve-2026-46633 Fix sandbox bypass: PHP code injection via {% use %} template name (alexandre-daubois, fabpot)
This PR was merged into the twig-3.x branch.
2026-05-19 23:00:20 +02:00
Fabien Potencier 679447fa29 Encode single quotes as \x27 in Compiler::string()
This is a defense-in-depth measure: callers must always concatenate the
result into a double-quoted PHP context, but if one ever (mistakenly)
embeds it inside a single-quoted PHP literal, an attacker-controlled
single quote in the source value could break out of that context. The
previous commit fixed exactly such a bug in ModuleNode for the {% use %}
template name.

Encoding ' as the hex escape \x27 guarantees that the emitted PHP source
never contains a literal single quote derived from user input, while the
decoded runtime value is unchanged. \' is not used because it is not a
recognized escape sequence in PHP double-quoted strings (the backslash
would be kept literally).
2026-05-19 22:58:27 +02:00
Alexandre Daubois e9ff55f691 Fix sandbox bypass: PHP code injection via {% use %} template name 2026-05-19 22:50:45 +02:00
Fabien Potencier afe54db2e5 security #cve-2026-46629 Fix unbounded memoisation of IntlDateFormatter / NumberFormatter (alexandre-daubois)
This PR was merged into the twig-3.x branch.
2026-05-19 22:47:15 +02:00
Alexandre Daubois 6add9066fc Fix unbounded memoisation of IntlDateFormatter / NumberFormatter 2026-05-19 22:44:48 +02:00
Fabien Potencier b675555ea2 security #cve-2026-46637 Fix XSS and pre-escape input on HTML-emitting filters in the extras (nicolas-grekas)
This PR was squashed before being merged into the twig-3.x branch.
2026-05-19 22:37:15 +02:00
Fabien Potencier e494400ce4 Fix deprecation 2026-05-19 22:05:26 +02:00
Fabien Potencier a8eb5a8a74 security #cve-2026-46639 Fix sandbox bypass in object destructuring assignment (alexandre-daubois)
This PR was merged into the twig-3.x branch.
2026-05-19 21:37:04 +02:00
Fabien Potencier c8dfd62064 security #cve-2026-24425 Fix sandbox bypass: propagate Source to checkArrow for source-policy sandboxing (fabpot)
This PR was merged into the twig-3.x branch.
2026-05-19 21:30:51 +02:00
Nicolas Grekas a5f6e8793e [Profiler] Escape template and profile names in HtmlDumper
The HtmlDumper output is intended to be rendered in a browser, and the
template and macro/block names it interpolates are loader-controlled
(e.g. the key for ArrayLoader or a database row id), so they can carry
arbitrary HTML when an application stores templates under user-supplied
identifiers.
2026-05-19 18:54:32 +02:00
Fabien Potencier 50535718b8 Bump version 2026-05-19 17:02:22 +02:00
Fabien Potencier 058a1789a9 Bump version 2026-05-17 08:41:52 +01:00
Fabien Potencier 0dade995be Prepare the 3.25.0 release v3.25.0 2026-05-17 08:41:26 +01:00
Fabien Potencier 9519a22752 Update CHANGELOG 2026-05-17 08:41:04 +01:00
Fabien Potencier fd0760d972 feature #4795 Lazy load EscaperRuntime in EscaperExtension (GromNaN)
This PR was merged into the 3.x branch.

Discussion
----------

Lazy load `EscaperRuntime` in `EscaperExtension`

This allows overriding `EscaperRuntime` via a custom runtime loader.

Previously, `EscaperExtension::setEnvironment()` was calling `$environment->getRuntime(EscaperRuntime::class)` eagerly. Since this method is called from `Environment::__construct()`, the runtime was resolved before any custom runtime loader could be injected, making it impossible to override `EscaperRuntime`.

- Required by https://github.com/symfony/symfony/pull/63929

Commits
-------

b73ab8cfd9 Lazy load EscaperRuntime in EscaperExtension
2026-05-17 07:52:38 +01:00
Fabien Potencier d0579ededc Fix sandbox bypass: propagate sandbox state to checkArrow for source-policy sandboxing 2026-05-16 18:56:08 +01:00
Fabien Potencier cec6bfb32b feature #4800 Add a needs_is_sandboxed option for filters, functions, and tests (fabpot)
This PR was merged into the 3.x branch.

Discussion
----------

Add a `needs_is_sandboxed` option for filters, functions, and tests

This PR introduces a new `needs_is_sandboxed` option for Twig callables.

When set to `true`, Twig passes the current sandbox state (enabled/disabled) as a boolean to the callable. This lets filters, functions, and tests adapt their behavior depending on whether the sandbox is enabled or not.

Commits
-------

5462817da0 Add a `needs_is_sandboxed` option for filters, functions, and tests
2026-05-16 18:53:36 +01:00
Fabien Potencier 5462817da0 Add a needs_is_sandboxed option for filters, functions, and tests 2026-05-16 18:52:17 +01:00
Fabien Potencier c3f37a5195 Bump version 2026-05-16 09:51:43 +01:00
Fabien Potencier 57c2c0f0ee bug #4797 Make embeds deterministic (itsalmostchristmas)
This PR was squashed before being merged into the 3.x branch.

Discussion
----------

Make embeds deterministic

Using `{% embed 'foo.twig' %}...{% endembed %}` makes compiled templates non-deterministic. This poses a problem for developers who wish to provide reproducible, pre-compiled builds of Twig templates.

The cause is `mt_rand()` used to generate template indices. The change I propose uses an incrementing counter instead. To keep tests passing, the number must be non-zero and unique per PHP process (reusing indices across `Twig\Parser` instances causes fatal errors).

A demonstration of the problem is available on the [Twig Playground](https://twig.symfony.com/play?data=eyJ0ZW1wbGF0ZXMiOltbImluZGV4LnR3aWciLCJ7JSBlbWJlZCAnZGlhbG9nLnR3aWcnICV9XG4gICAgeyUgYmxvY2sgbWVzc2FnZSAlfVxuICAgICAgICBUYXNrIGZhaWxlZCBzdWNjZXNzZnVsbHlcbiAgICB7JSBlbmRibG9jayAlfVxueyUgZW5kZW1iZWQgJX0iXSxbImRpYWxvZy50d2lnIiwiPGRpYWxvZz57JSBibG9jayBtZXNzYWdlICV9eyUgZW5kYmxvY2sgJX08L2RpYWxvZz4iXV0sImNvbnRleHQiOnt9LCJ2ZXJzaW9uIjoiMy4yMS4xIiwib3B0aW9ucyI6eyJzdHJpY3RfdmFyaWFibGVzIjp0cnVlLCJjaGFyc2V0IjoiVVRGLTgiLCJhdXRvZXNjYXBlIjoiIn19), where the compiled output of `index.twig` differs on every recompilation.

Commits
-------

2b4aa4458a Make embeds deterministic
2026-05-16 09:48:31 +01:00
itsalmostchristmas 2b4aa4458a Make embeds deterministic 2026-05-16 09:48:23 +01:00
Nicolas Grekas e36489d352 Pre-escape HTML input on inline_css and inky_to_html filters
Both filters consume HTML on the input side. Adding `pre_escape => 'html'`
makes the autoescaper escape attacker-controlled inputs before the filters
process them, so they are no longer reachable via `{{ user_input|inline_css }}`
or `{{ user_input|inky_to_html }}` without an explicit `|raw`.
2026-05-15 15:14:14 +02:00
Nicolas Grekas 84982072c7 Fix XSS by adjusting is_safe annotation on HTML-emitting filters
The `html_to_markdown` filter emits plain Markdown text, so the
`is_safe` annotation is dropped entirely and autoescape now handles
its output according to the surrounding context.

The `markdown_to_html` and `inline_css` filters emit HTML, not text
safe in every escaping context, so `is_safe => ['all']` produced
unescaped HTML when their output was interpolated into a JS, CSS or
URL context. The annotation is now `is_safe => ['html']`.
2026-05-15 15:14:02 +02:00
Fabien Potencier ab8dd4aadd minor #4799 [Doc] Document loose comparison in the in operator (Amoifr)
This PR was merged into the 3.x branch.

Discussion
----------

[Doc] Document loose comparison in the `in` operator

Clarifies the comparison semantics of the `in` operator in the *Containment Operators* section of `doc/templates.rst`:

- `in` uses a loose comparison (similar to `==`) for sequences, mappings, and `Traversable` objects, like PHP's `in_array()`.
- Pointer to `same as` for strict comparisons.
- Warning about boolean left operands (e.g. `true in ['foo', 'bar']` returns `true`), which surprises users.
- Note that string containment only accepts `string`, `int`, `float` on the left.

Closes #4650 (or at least the documentation half of it — the `Investigate before 4.x` label suggests the maintainers may want to revisit the actual semantics in 4.x; this PR addresses `@gorenstein`'s explicit request to "at least improve the documentation").

Commits
-------

8af8e93970 [Doc] Document loose comparison in the `in` operator
2026-05-14 18:42:46 +01:00
Fabien Potencier f765a753fb minor #4798 [Doc] Reword whitespace control note about first-newline removal (Amoifr)
This PR was merged into the 3.x branch.

Discussion
----------

[Doc] Reword whitespace control note about first-newline removal

Fixes #4720.

The wording on line 1224 of `doc/templates.rst` ("removal of the first newline **inherited from PHP**") was misleading — Twig does not inherit anything from PHP, it deliberately implements the same behavior (just like Jinja does, which uses *"like in PHP"* in its own documentation).

The note already exists a few lines above (line 1210: *"The first newline after a template tag is removed automatically (like in PHP)."*), so the second mention can just point back to it instead of duplicating the (incorrect) attribution.

Commits
-------

6904b23fb6 [Doc] Reword whitespace control note about first-newline removal
2026-05-14 18:41:00 +01:00
Pascal CESCON - Amoifr 8af8e93970 [Doc] Document loose comparison in the in operator
Clarifies that `in` performs a loose comparison on sequences, mappings,
and `Traversable` objects (similar to `==`), points to `same as` for
strict comparisons, and warns about boolean left operands.

Refs #4650
2026-05-08 18:35:48 +02:00