diff --git a/app/config/eccube/packages/twig_extensions.yaml b/app/config/eccube/packages/twig_extensions.yaml index b9ecee2c3c8..6b713dd5d22 100644 --- a/app/config/eccube/packages/twig_extensions.yaml +++ b/app/config/eccube/packages/twig_extensions.yaml @@ -23,6 +23,8 @@ services: - '@eccube.twig_sandbox.policy' - false tags: ['twig.extension'] + Eccube\Twig\Sandbox\SecurityPolicyDecorator: + decorates: 'eccube.twig_sandbox.policy' parameters: eccube.twig_sandbox.allowed_tags: - 'apply' diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 213da6dad2a..b44c21c8885 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,2 +1,6 @@ parameters: level: 1 + ignoreErrors: + - + message: "#^Function twig_include not found\\.$#" + path: src/Eccube/Twig/Extension/IgnoreTwigSandboxErrorExtension.php \ No newline at end of file diff --git a/src/Eccube/Twig/Sandbox/SecurityPolicyDecorator.php b/src/Eccube/Twig/Sandbox/SecurityPolicyDecorator.php new file mode 100644 index 00000000000..8615449624b --- /dev/null +++ b/src/Eccube/Twig/Sandbox/SecurityPolicyDecorator.php @@ -0,0 +1,47 @@ +securityPolicy = $securityPolicy; + } + + public function checkSecurity($tags, $filters, $functions) + { + $this->securityPolicy->checkSecurity($tags, $filters, $functions); + } + + public function checkMethodAllowed($obj, $method) + { + // __toStringの場合はチェックをスキップする + if ($method === '__toString') { + return; + } + $this->securityPolicy->checkMethodAllowed($obj, $method); + } + + public function checkPropertyAllowed($obj, $method) + { + $this->securityPolicy->checkPropertyAllowed($obj, $method); + } +} \ No newline at end of file diff --git a/tests/Eccube/Tests/Twig/Extension/IgnoreTwigSandboxErrorExtensionTest.php b/tests/Eccube/Tests/Twig/Extension/IgnoreTwigSandboxErrorExtensionTest.php index 1a1869b06b1..cac1c1b2fc8 100644 --- a/tests/Eccube/Tests/Twig/Extension/IgnoreTwigSandboxErrorExtensionTest.php +++ b/tests/Eccube/Tests/Twig/Extension/IgnoreTwigSandboxErrorExtensionTest.php @@ -48,8 +48,15 @@ public function testMetatags($snippet, $whitelisted) $crawler = $this->client->request('GET', $this->generateUrl($Page->getUrl())); $text = $crawler->text(); - // $snippetがsandboxで制限された場合はメタタグエリアは空で出力されるため、__RENDERED__の出力有無で結果を確認する - self::assertStringContainsString($whitelisted ? '__RENDERED__' : '', $text); + // ホワイトリストに入っている場合__RENDERED__が表示される + if ($whitelisted) { + self::assertStringContainsString('__RENDERED__', $text); + } else { + self::assertStringNotContainsString('__RENDERED__', $text); + } + // 入力可能ではない値の場合は、システムエラーが発生する + self::assertStringNotContainsString('システムエラーが発生しました', $text); + } public function twigSnippetsProvider() @@ -59,7 +66,7 @@ public function twigSnippetsProvider() ['{% set foo = "bar" %}', true], ['{% spaceless %}
test
{% endspaceless %}', true], ['{% flush %}', true], - ['{% apply lower|escape("html") %}SOME TEXT{% endapply %}', false], + ['{% apply lower|escape("html") %}SOME TEXT{% endapply %}', true], ['{% macro input(name, value, type = "text", size = 20) %}{% endmacro %}', false], ['{% sandbox %}{% include "user.html" %}{% endsandbox %}', false], ['{{ "-5"|abs }}', true], @@ -74,6 +81,7 @@ public function twigSnippetsProvider() ['{{ dump(9) }}', false], ['{{ constant("RSS", date) }}', false], ['{{ include(template_from_string("Hello")) }}', false], + ['{{ Product.main_list_image|no_image_product }}', true], ]; }