Deprecate the sandbox tag

This commit is contained in:
Fabien Potencier
2024-09-09 22:30:28 +02:00
parent a3496d148b
commit 9369a48c53
10 changed files with 51 additions and 10 deletions
+1
View File
@@ -1,5 +1,6 @@
# 3.15.0 (2024-XX-XX)
* Deprecate the `sandbox` tag
* Improve the way one can deprecate a Twig callable (use `deprecation_info` instead of the other callable options)
# 3.14.0 (2024-09-09)
+3 -4
View File
@@ -498,13 +498,12 @@ The policy object is the first argument of the sandbox constructor::
$twig->addExtension($sandbox);
By default, the sandbox mode is disabled and should be enabled when including
untrusted template code by using the ``sandbox`` tag:
untrusted template code by using the ``sandboxed`` option of the ``include``
function:
.. code-block:: twig
{% sandbox %}
{% include 'user.html' %}
{% endsandbox %}
{{ include('user.html', sandboxed: true) }}
You can sandbox all templates by passing ``true`` as the second argument of
the extension constructor::
+13
View File
@@ -201,6 +201,19 @@ Sandbox
deprecated as of Twig 3.12. You will need to explicitly allow them if needed
in 4.0.
* Deprecate the ``sandbox`` tag, use the ``sandboxed`` option of the
``include`` function instead:
Before::
{% sandbox %}
{% include 'foo.twig' %}
{% endsandbox %}
After::
{{ include('foo.twig', sandboxed: true) }}
Testing Utilities
-----------------
+5
View File
@@ -1,6 +1,11 @@
``sandbox``
===========
.. warning::
The ``sandbox`` tag is deprecated as of Twig 3.15.
Use the ``sandboxed`` option of the ``include`` function instead.
The ``sandbox`` tag can be used to enable the sandboxing mode for an included
template, when sandboxing is not enabled globally for the Twig environment:
+2
View File
@@ -34,6 +34,8 @@ final class SandboxTokenParser extends AbstractTokenParser
public function parse(Token $token): Node
{
$stream = $this->parser->getStream();
trigger_deprecation('twig/twig', '3.15', \sprintf('The "sandbox" tag is deprecated in "%s" at line %d.', $stream->getSourceContext()->getName(), $token->getLine()));
$stream->expect(Token::BLOCK_END_TYPE);
$body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
$stream->expect(Token::BLOCK_END_TYPE);
+21 -6
View File
@@ -60,7 +60,8 @@ class SandboxTest extends TestCase
'1_basic2_include_template_from_string_sandboxed' => '{{ include(template_from_string("{{ name|upper }}"), sandboxed=true) }}',
'1_basic2_include_template_from_string' => '{{ include(template_from_string("{{ name|upper }}")) }}',
'1_range_operator' => '{{ (1..2)[0] }}',
'1_syntax_error_wrapper' => '{% sandbox %}{% include "1_syntax_error" %}{% endsandbox %}',
'1_syntax_error_wrapper_legacy' => '{% sandbox %}{% include "1_syntax_error" %}{% endsandbox %}',
'1_syntax_error_wrapper' => '{{ include("1_syntax_error", sandboxed: true) }}',
'1_syntax_error' => '{% syntax error }}',
'1_childobj_parentmethod' => '{{ child_obj.ParentMethod() }}',
'1_childobj_childmethod' => '{{ child_obj.ChildMethod() }}',
@@ -98,7 +99,6 @@ class SandboxTest extends TestCase
yield ['import', '{% import "macros" as macros %}'];
yield ['include', '{% include "macros" %}'];
yield ['macro', '{% macro foo() %}{% endmacro %}'];
yield ['sandbox', '{% sandbox %}{% endsandbox %}'];
yield ['set', '{% set foo = 1 %}'];
// To be uncommented in 4.0
// yield ['use', '{% use "1_empty" %}'];
@@ -152,6 +152,21 @@ class SandboxTest extends TestCase
}
}
/**
* @group legacy
*/
public function testIfSandBoxIsDisabledAfterSyntaxErrorLegacy()
{
$twig = $this->getEnvironment(false, [], self::$templates);
try {
$twig->load('1_syntax_error_wrapper_legacy')->render(self::$params);
} catch (SyntaxError $e) {
/** @var SandboxExtension $sandbox */
$sandbox = $twig->getExtension(SandboxExtension::class);
$this->assertFalse($sandbox->isSandboxed());
}
}
public function testIfSandBoxIsDisabledAfterSyntaxError()
{
$twig = $this->getEnvironment(false, [], self::$templates);
@@ -399,16 +414,16 @@ class SandboxTest extends TestCase
$this->assertEquals('fooFOOfoo', $twig->load('2_basic')->render(self::$params), 'Sandbox does nothing if disabled globally and sandboxed not used for the include');
self::$templates = [
'3_basic' => '{{ obj.foo }}{% sandbox %}{% include "3_included" %}{% endsandbox %}{{ obj.foo }}',
'3_included' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}',
'3_basic' => '{{ include("3_included", sandboxed: true) }}',
'3_included' => '{% if true %}{{ "foo"|upper }}{% endif %}',
];
$twig = $this->getEnvironment(true, [], self::$templates);
$twig = $this->getEnvironment(true, [], self::$templates, functions: ['include']);
try {
$twig->load('3_basic')->render(self::$params);
$this->fail('Sandbox throws a SecurityError exception when the included file is sandboxed');
} catch (SecurityNotAllowedTagError $e) {
$this->assertEquals('sandbox', $e->getTagName());
$this->assertEquals('if', $e->getTagName());
}
}
@@ -1,5 +1,7 @@
--TEST--
sandbox tag
--DEPRECATION--
Since twig/twig 3.15: The "sandbox" tag is deprecated in "index.twig" at line 2.
--TEMPLATE--
{%- sandbox %}
{%- include "foo.twig" %}
@@ -1,5 +1,9 @@
--TEST--
sandbox tag
--DEPRECATION--
Since twig/twig 3.15: The "sandbox" tag is deprecated in "index.twig" at line 2.
Since twig/twig 3.15: The "sandbox" tag is deprecated in "index.twig" at line 6.
Since twig/twig 3.15: The "sandbox" tag is deprecated in "index.twig" at line 11.
--TEMPLATE--
{%- sandbox %}
{%- include "foo.twig" %}