Skip to content

Commit

Permalink
Merge pull request #6058 from EC-CUBE/dev/4.2_twig_sandbox
Browse files Browse the repository at this point in the history
脆弱性対応
  • Loading branch information
shinya committed Nov 6, 2023
2 parents 81b68e7 + c07e298 commit daed16e
Show file tree
Hide file tree
Showing 7 changed files with 403 additions and 2 deletions.
163 changes: 163 additions & 0 deletions app/config/eccube/packages/twig_extensions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,166 @@ services:
#Twig\Extensions\DateExtension: ~
# Twig\Extensions\IntlExtension: ~
#Twig\Extensions\TextExtension: ~

eccube.twig_sandbox.policy:
class: Twig\Sandbox\SecurityPolicy
arguments:
$allowedTags: "%eccube.twig_sandbox.allowed_tags%"
$allowedFilters: "%eccube.twig_sandbox.allowed_filters%"
$allowedFunctions: "%eccube.twig_sandbox.allowed_functions%"
$allowedMethods: "%eccube.twig_sandbox.allowed_methods%"
$allowedProperties: "%eccube.twig_sandbox.allowed_properties%"
eccube.twig_sandbox.extension:
class: Twig\Extension\SandboxExtension
arguments:
- '@eccube.twig_sandbox.policy'
- false
tags: ['twig.extension']
Eccube\Twig\Sandbox\SecurityPolicyDecorator:
decorates: 'eccube.twig_sandbox.policy'
parameters:
eccube.twig_sandbox.allowed_tags:
- 'apply'
- 'block'
- 'deprecated'
- 'embed'
- 'extends'
- 'flush'
- 'for'
- 'if'
- 'set'
- 'spaceless'
- 'verbatim'
- 'with'
- 'form_theme'
- 'stopwatch'
- 'trans'
- 'trans_default_domain'
eccube.twig_sandbox.allowed_filters:
- 'abs'
- 'batch'
- 'capitalize'
- 'column'
- 'convert_encoding'
- 'country_name'
- 'currency_name'
- 'currency_symbol'
- 'date'
- 'date_modify'
- 'default'
- 'escape'
- 'first'
- 'format'
- 'format_currency'
- 'format_date'
- 'format_datetime'
- 'format_number'
- 'format_time'
- 'join'
- 'json_encode'
- 'keys'
- 'language_name'
- 'last'
- 'length'
- 'locale_name'
- 'lower'
- 'merge'
- 'nl2br'
- 'number_format'
- 'replace'
- 'reverse'
- 'round'
- 'slice'
- 'spaceless'
- 'split'
- 'striptags'
- 'timezone_name'
- 'title'
- 'trim'
- 'upper'
- 'url_encode'
- 'abbr_class'
- 'abbr_method'
- 'file_link'
- 'file_relative'
- 'format_args'
- 'format_args_as_text'
- 'humanize'
- 'serialize'
- 'trans'
- 'yaml_dump'
- 'yaml_encode'
- 'currency_symbol'
- 'date_day'
- 'date_day_with_weekday'
- 'date_format'
- 'date_min'
- 'date_sec'
- 'doctrine_format_sql'
- 'doctrine_prettify_sql'
- 'doctrine_pretty_query'
- 'doctrine_replace_query_parameters'
- 'e'
- 'ellipsis'
- 'file_ext_icon'
- 'form_encode_currency'
- 'format_*_number'
- 'format_log_message'
- 'no_image_product'
- 'price'
- 'purify'
- 'time_ago'
eccube.twig_sandbox.allowed_functions:
- 'cycle'
- 'date'
- 'max'
- 'min'
- 'random'
- 'range'
- 'country_timezones'
- 'absolute_url'
- 'asset'
- 'asset_version'
- 'csrf_token'
- 'form_parent'
- 'fragment_uri'
- 'impersonation_exit_path'
- 'impersonation_exit_url'
- 'is_granted'
- 'logout_path'
- 'logout_url'
- 'path'
- 'relative_path'
- 't'
- 'url'
- 'active_menus'
- 'class_categories_as_json'
- 'country_names'
- 'csrf_token_for_anchor'
- 'currency_names'
- 'currency_symbol'
- 'field_choices'
- 'field_errors'
- 'field_help'
- 'field_label'
- 'field_name'
- 'field_value'
- 'get_all_carts'
- 'get_cart'
- 'get_carts_total_price'
- 'get_carts_total_quantity'
- 'has_errors'
- 'is_reduced_tax_rate'
- 'language_names'
- 'product'
- 'workflow_can'
- 'workflow_has_marked_place'
- 'workflow_marked_places'
- 'workflow_metadata'
- 'workflow_transition'
- 'workflow_transition_blockers'
- 'workflow_transitions'
eccube.twig_sandbox.allowed_methods:
'Symfony\Bridge\Twig\AppVariable': [ 'getrequest' ]
'Symfony\Component\HttpFoundation\Request': [ 'geturi' ]
eccube.twig_sandbox.allowed_properties: []
4 changes: 4 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
parameters:
level: 1
ignoreErrors:
-
message: "#^Function twig_include not found\\.$#"
path: src/Eccube/Twig/Extension/IgnoreTwigSandboxErrorExtension.php
2 changes: 1 addition & 1 deletion src/Eccube/Resource/template/default/Product/detail.twig
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ file that was distributed with this source code.
</div>
{% if Product.freearea %}
<div class="ec-productRole__description">
{{ include(template_from_string(Product.freearea)) }}
{{ include(template_from_string(Product.freearea), sandboxed = true) }}
</div>
{% endif %}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/Eccube/Resource/template/default/default_frame.twig
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ file that was distributed with this source code.
<meta name="eccube-csrf-token" content="{{ csrf_token(constant('Eccube\\Common\\Constant::TOKEN_NAME')) }}">
<title>{{ BaseInfo.shop_name }}{% if subtitle is defined and subtitle is not empty %} / {{ subtitle }}{% elseif title is defined and title is not empty %} / {{ title }}{% endif %}</title>
{% if Page.meta_tags is not empty %}
{{ include(template_from_string(Page.meta_tags)) }}
{{ include(template_from_string(Page.meta_tags), sandboxed = true) }}
{% if Page.description is not empty %}
<meta name="description" content="{{ Page.description }}">
{% endif %}
Expand Down
78 changes: 78 additions & 0 deletions src/Eccube/Twig/Extension/IgnoreTwigSandboxErrorExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

/*
* This file is part of EC-CUBE
*
* Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
*
* http://www.ec-cube.co.jp/
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Eccube\Twig\Extension;

use Twig\Environment;
use Twig\Error\LoaderError;
use Twig\Extension\AbstractExtension;
use Twig\Extension\SandboxExtension;
use Twig\Sandbox\SecurityError;
use Twig\TwigFunction;

/**
* \vendor\twig\twig\src\Extension\CoreExtension の拡張
*/
class IgnoreTwigSandboxErrorExtension extends AbstractExtension
{
/**
* {@inheritdoc}
*/
public function getFunctions(): array
{
return [
new TwigFunction('include', [$this, 'twig_include'], ['needs_environment' => true, 'needs_context' => true, 'is_safe' => ['all']]),
];
}

/**
* twig sandboxの例外を操作します
* app_env = devの場合、エラーを表示する
* app_env = prodの場合、エラーを表示しない
*
* @param Environment $env
* @param $context
* @param $template
* @param $variables
* @param $withContext
* @param $ignoreMissing
* @param $sandboxed
*
* @return string|void
*
* @throws LoaderError
* @throws SecurityError
*/
public function twig_include(Environment $env, $context, $template, $variables = [], $withContext = true, $ignoreMissing = false, $sandboxed = false)
{
try {
return \twig_include($env, $context, $template, $variables, $withContext, $ignoreMissing, $sandboxed);
} catch (SecurityError $e) {

// devではエラー画面が表示されるようにする
$appEnv = env('APP_ENV');
if ($appEnv === 'dev') {
throw $e;
} else {
// ログ出力
log_warning($e->getMessage(), ['exception' => $e]);

// 例外がスローされた場合、sandboxが効いた状態になってしまうため追加
$sandbox = $env->getExtension(SandboxExtension::class);
if (!$sandbox->isSandboxedGlobally()) {
$sandbox->disableSandbox();
}
}
}
}
}
47 changes: 47 additions & 0 deletions src/Eccube/Twig/Sandbox/SecurityPolicyDecorator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

/*
* This file is part of EC-CUBE
*
* Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
*
* http://www.ec-cube.co.jp/
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Eccube\Twig\Sandbox;

use Twig\Sandbox\SecurityPolicy as BasePolicy;
use Twig\Sandbox\SecurityPolicyInterface;

class SecurityPolicyDecorator implements SecurityPolicyInterface {

/** @var BasePolicy */
private $securityPolicy;

public function __construct(BasePolicy $securityPolicy)
{
$this->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);
}
}

0 comments on commit daed16e

Please sign in to comment.