EC-CUBE3系におけるRCE可能な脆弱性(JVN#29195731)

更新履歴
2023/12/05 11:30
旧バージョンでの対応方法を追加
2023/11/29 17:00
エラーが表示された場合の対応方法を追加
2023/11/17 11:00
Twigの更新手順の追加
2023/11/09 15:00
目次の追加
2023/11/07 14:00
JVNからの公表内容情報へのリンクを追加
2023/10/26 13:00
初版公開

目次

EC-CUBEにおけるRCE可能な脆弱性

EC-CUBE 3系におけるRCE可能な脆弱性(危険度: 低)があることが判明いたしました。

脆弱性そのものは、修正の反映によりすぐに解決するものです。
以下のいずれかの方法により、ご対応をお願いいたします。

皆様にはお手数おかけし誠に申し訳ございません。
本脆弱性における被害報告は現時点でございませんが、できるだけ速やかにご対応をお願いいたします。

脆弱性の概要

EC-CUBEにおけるRCE可能な脆弱性

危険度:

不具合が存在するEC-CUBEのバージョン:

詳細:

該当バージョンのEC-CUBEにはRCE可能な脆弱性が存在します。EC-CUBEはテンプレートエンジンとしてTwigを利用していますが、EC-CUBEの一部画面でTwigに対する設定不備が存在し、攻撃者が対象のシステム上で任意のコードを実行できる可能性があります。


JVNからの公表内容 (2023/11/07公開)

JVN#29195731: EC-CUBE 3系および 4系において任意のコードを実行される脆弱性

修正ファイル適用による注意点

以下のエラーが表示された場合についての対応

今回のパッチを適用した際に、以下のような画面に遭遇した場合 error_screen

ClassNotFoundException in SandboxServiceProvider.php line 33:
Attempted to load class "SecurityPolicy" from namespace "Twig\Sandbox".
Did you forget a "use" statement for "Twig_Sandbox_SecurityPolicy"?

画面に上記のエラーが出た場合は、キャッシュの削除が不十分 or Twigの更新がうまく行っていない可能性が考えられます。 今一度ご確認をお願いします。なお、Twigの更新方法に関しては下記で解説しておりますので、ご参考ください。

また、EC-CUBE 3.0系の旧バージョンを使用し、Twigのバージョンが1.34.0未満の場合、Twigの変更により名前空間構造やクラス名などが1.34.0以前と1.34.0以降で異なり、以前のバージョンとの互換性がなくなり、ファイルが正しく読み込まれない可能性があります。その際には、以下のようにコードを修正してください。

src/Eccube/ServiceProvider/SandboxServiceProvider.php CHANGED
@@ -33,2 +33,2 @@ class SandboxServiceProvider implements ServiceProviderInterface
33
- $policy = new \Twig\Sandbox\SecurityPolicy($tags, $filters, $methods, $properties, $functions);
34
- $sandbox = new \Twig\Extension\SandboxExtension($policy);
33
+ $policy = new \Twig_Sandbox_SecurityPolicy($tags, $filters, $methods, $properties, $functions);
34
+ $sandbox = new \Twig_Extension_Sandbox($policy);

フリーエリア(商品詳細画面)の挙動について

本修正ファイルを適用することにより、TwigのSandBox機能が有効になります。
Sandboxは指定されたTwigのタグ、関数、フィルターのみを許可します。
そのため、「商品情報>商品登録>フリーエリア」で指定されたTwigのタグ、関数、フィルター以外を使用している場合、フロントでは、フリーエリアの登録情報が表示されなくなります。
ただし、フリーエリアの箇所以外の商品情報は通常通り表示されます。
この点をあらかじめご了承ください。
src/Eccube/Resource/config/twig_sandbox.yml.distで、利用しているTwigのタグ、関数、フィルターを登録することで、それらを利用可能にすることができます。

修正の際、allowed_*** の部分に必要な内容を追加してください。
以下のymlファイルを参考にしてください。
twig_sandbox.yml.dist

Twigの更新手順

EC-CUBE3.0系の旧バージョンを利用している場合、Twigのアップデートを行ってください。
すでにTwigの「v1.34.0」のバージョンをご利用中の場合は、ご対応いただく必要はありません。

Twigをアップデートするためには、composerを使用する方法とファイルを手動でアップデートする方法の2つがあります。
以下のどちらかを実施してください。

修正方法1: 修正ファイルを利用する場合(3.0系)

開発環境がある場合は、まず開発環境でお試しください。
以下の手順に従って、修正ファイルの反映をお願いいたします。

  1. 修正ファイルのダウンロード

    ご利用中のEC-CUBEのバージョンに該当する修正ファイルをダウンロードしてください。
    ※EC-CUBEのバージョンはこちらの手順でご確認ください。
    ※修正ファイルは各バージョンの最新版に対して作成しています。旧バージョンをご利用の場合は、「修正方法2」のご対応をお願いします。
    ※対象のファイルに対して既にカスタマイズをしている場合は、「修正方法2」のご対応をお願いします。

    ダウンロードし、解凍していただきますと、以下の修正ファイルがあります。必ず該当するバージョンのファイルをご利用ください。

    3.0.18-p6

    • src/Eccube/Application.php
    • src/Eccube/Resource/config/twig_sandbox.yml.dist
    • src/Eccube/Resource/template/default/Product/detail.twig
    • src/Eccube/ServiceProvider/SandboxServiceProvider.php
    • src/Eccube/Twig/Extension/IgnoreTwigSandboxErrorExtension.php
  2. EC-CUBEファイルのバックアップ

    あらかじめEC-CUBEファイル全体のバックアップを行ってください。

  3. 修正ファイルの反映

    以下のファイルを上書き更新してください。

    上書きするファイル

    3.0.18-p6

    • src/Eccube/Application.php
    • src/Eccube/Resource/config/twig_sandbox.yml.dist
    • src/Eccube/Resource/template/default/Product/detail.twig
    • src/Eccube/ServiceProvider/SandboxServiceProvider.php
    • src/Eccube/Twig/Extension/IgnoreTwigSandboxErrorExtension.php

    下記にファイルが存在する場合は同様に上書きをお願いします

    • app/template/default/Product/detail.twig
    ※デザインテンプレートの適用や、EC-CUBE本体のカスタマイズをしている場合、修正箇所の差分をご確認のうえ反映をお願いします。
    ※開発環境がある場合は、開発環境での反映・動作確認を行った後に、本番環境への反映をおすすめします。

  4. キャッシュの削除

    EC-CUBE のキャッシュの削除が必要です。
    EC-CUBE の管理画面にログインいただき、コンテンツ管理 -> キャッシュ管理 のページからキャッシュの削除をお願いいたします。

  5. 動作確認

    フロント画面と管理画面(ログインが必要)それぞれにおいて、基本操作が正常に行えることをご確認ください。

修正方法2: 修正差分を確認して適宜反映する場合(3.0系)

以下のコード差分情報を参照して頂き、必要な箇所に修正を反映してください。

本修正方法はEC-CUBE 3.0.18-p6のバージョンを例として提示しております。
過去バージョンをご利用の場合は、下記修正対象ファイルの修正差分を参考にご対応お願いいたします。

修正差分

src/Eccube/Application.php CHANGED
@@ -105,7 +105,8 @@ class Application extends ApplicationTrait
105
105
  ->parseConfig('nav', $configAll, true)
106
106
  ->parseConfig('doctrine_cache', $configAll)
107
107
  ->parseConfig('http_cache', $configAll)
108
- ->parseConfig('session_handler', $configAll);
108
+ ->parseConfig('session_handler', $configAll)
109
+ ->parseConfig('twig_sandbox', $configAll);
109
110
 
110
111
  return $configAll;
111
112
  });
@@ -285,6 +286,7 @@ class Application extends ApplicationTrait
285
286
  $this->register(new \Silex\Provider\TwigServiceProvider(), array(
286
287
  'twig.form.templates' => array('Form/form_layout.twig'),
287
288
  ));
289
+ $this->register(new \Eccube\ServiceProvider\SandboxServiceProvider());
288
290
  $this['twig'] = $this->share($this->extend('twig', function (\Twig_Environment $twig, \Silex\Application $app) {
289
291
  $twig->addExtension(new \Eccube\Twig\Extension\EccubeExtension($app));
290
292
  $twig->addExtension(new \Twig_Extension_StringLoader());
src/Eccube/Resource/config/twig_sandbox.yml.dist ADDED
@@ -0,0 +1,91 @@
1
+ twig_sandbox:
2
+ allowed_tags:
3
+ - 'block'
4
+ - 'extends'
5
+ - 'for'
6
+ - 'if'
7
+ - 'set'
8
+ - 'spaceless'
9
+ - 'verbatim'
10
+ - 'with'
11
+ - 'form_theme'
12
+ - 'stopwatch'
13
+ - 'trans'
14
+ - 'trans_default_domain'
15
+ allowed_filters:
16
+ - 'abs'
17
+ - 'batch'
18
+ - 'capitalize'
19
+ - 'date'
20
+ - 'escape'
21
+ - 'default'
22
+ - 'doctrine_format_sql'
23
+ - 'doctrine_prettify_sql'
24
+ - 'doctrine_pretty_query'
25
+ - 'doctrine_replace_query_parameters'
26
+ - 'first'
27
+ - 'format'
28
+ - 'abbr_class'
29
+ - 'abbr_method'
30
+ - 'file_link'
31
+ - 'file_relative'
32
+ - 'format_args'
33
+ - 'format_args_as_text'
34
+ - 'humanize'
35
+ - 'json_encode'
36
+ - 'keys'
37
+ - 'last'
38
+ - 'length'
39
+ - 'lower'
40
+ - 'merge'
41
+ - 'replace'
42
+ - 'round'
43
+ - 'split'
44
+ - 'striptags'
45
+ - 'title'
46
+ - 'trim'
47
+ - 'no_image_product'
48
+ - 'date_format'
49
+ - 'price'
50
+ - 'ellipsis'
51
+ - 'time_ago'
52
+ - 'upper'
53
+ - 'date_modify'
54
+ - 'escape'
55
+ - 'nl2br'
56
+ - 'number_format'
57
+ - 'slice'
58
+ - 'split'
59
+ - 'striptags'
60
+ allowed_functions:
61
+ - 'cycle'
62
+ - 'max'
63
+ - 'min'
64
+ - 'random'
65
+ - 'range'
66
+ - 'template_from_string'
67
+ - 'absolute_url'
68
+ - 'asset'
69
+ - 'asset_version'
70
+ - 'csrf_token'
71
+ - 'form_parent'
72
+ - 'fragment_uri'
73
+ - 'impersonation_exit_path'
74
+ - 'impersonation_exit_url'
75
+ - 'is_granted'
76
+ - 'logout_path'
77
+ - 'logout_url'
78
+ - 'path'
79
+ - 'relative_path'
80
+ - 't'
81
+ - 'url'
82
+ - 'calc_inc_tax'
83
+ - 'active_menus'
84
+ - 'csrf_token_for_anchor'
85
+ - 'url'
86
+ - 'path'
87
+ - 'is_object'
88
+ - 'get_product'
89
+ - 'date'
90
+ allowed_methods: []
91
+ allowed_properties: []
src/Eccube/Resource/template/default/Product/detail.twig CHANGED
@@ -278,7 +278,7 @@ $(function(){
278
278
  {% if Product.freearea %}
279
279
  <div id="sub_area" class="row">
280
280
  <div class="col-sm-10 col-sm-offset-1">
281
- <div id="detail_free_box__freearea" class="freearea">{{ include(template_from_string(Product.freearea)) }}</div>
281
+ <div id="detail_free_box__freearea" class="freearea">{{ include(template_from_string(Product.freearea), sandboxed = true) }}</div>
282
282
  </div>
283
283
  </div>
284
284
  {% endif %}
src/Eccube/ServiceProvider/SandboxServiceProvider.php ADDED
@@ -0,0 +1,46 @@
1
+ <?php
2
+
3
+ namespace Eccube\ServiceProvider;
4
+
5
+ use Eccube\EventListener\LogListener;
6
+ use Eccube\Log\Logger;
7
+ use Eccube\Log\Monolog\Helper\LogHelper;
8
+ use Eccube\Twig\Extension\IgnoreTwigSandboxErrorExtension;
9
+ use Silex\Application;
10
+ use Silex\ServiceProviderInterface;
11
+ use Symfony\Bridge\Twig\Extension\DumpExtension;
12
+
13
+ /**
14
+ * Class LogServiceProvider
15
+ *
16
+ * @package Eccube\ServiceProvider
17
+ */
18
+ class SandboxServiceProvider implements ServiceProviderInterface
19
+ {
20
+ public function register(Application $app)
21
+ {
22
+ $app['twig'] = $app->share($app->extend('twig', function ($twig, $app) {
23
+
24
+ // ホワイトリストの設定
25
+ $twig_sandbox_list = $app['config']['twig_sandbox'];
26
+
27
+ $tags = $twig_sandbox_list['allowed_tags'];
28
+ $filters = $twig_sandbox_list['allowed_filters'];
29
+ $methods = $twig_sandbox_list['allowed_methods'];
30
+ $properties = $twig_sandbox_list['allowed_properties'];
31
+ $functions = $twig_sandbox_list['allowed_functions'];
32
+
33
+ $policy = new \Twig\Sandbox\SecurityPolicy($tags, $filters, $methods, $properties, $functions);
34
+ $sandbox = new \Twig\Extension\SandboxExtension($policy);
35
+
36
+ $twig->addExtension($sandbox);
37
+ $twig->addExtension(new IgnoreTwigSandboxErrorExtension());
38
+
39
+ return $twig;
40
+ }));
41
+ }
42
+
43
+ public function boot(Application $app)
44
+ {
45
+ }
46
+ }
src/Eccube/Twig/Extension/IgnoreTwigSandboxErrorExtension.php ADDED
@@ -0,0 +1,78 @@
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of EC-CUBE
5
+ *
6
+ * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
7
+ *
8
+ * http://www.ec-cube.co.jp/
9
+ *
10
+ * For the full copyright and license information, please view the LICENSE
11
+ * file that was distributed with this source code.
12
+ */
13
+
14
+ namespace Eccube\Twig\Extension;
15
+
16
+ use Twig\Environment;
17
+ use Twig\Error\LoaderError;
18
+ use Twig\Extension\AbstractExtension;
19
+ use Twig\Extension\SandboxExtension;
20
+ use Twig\Sandbox\SecurityError;
21
+ use Twig\TwigFunction;
22
+
23
+ /**
24
+ * \vendor\twig\twig\src\Extension\CoreExtension の拡張
25
+ */
26
+ class IgnoreTwigSandboxErrorExtension extends AbstractExtension
27
+ {
28
+ /**
29
+ * {@inheritdoc}
30
+ */
31
+ public function getFunctions()
32
+ {
33
+ return array(
34
+ new \Twig_SimpleFunction('include', array($this, 'twig_include'), array('needs_environment' => true, 'needs_context' => true, 'is_safe' => array('all'))),
35
+ );
36
+ }
37
+
38
+ /**
39
+ * twig sandboxの例外を操作します
40
+ * app_env = devの場合、エラーを表示する
41
+ * app_env = prodの場合、エラーを表示しない
42
+ *
43
+ * @param Environment $env
44
+ * @param $context
45
+ * @param $template
46
+ * @param $variables
47
+ * @param $withContext
48
+ * @param $ignoreMissing
49
+ * @param $sandboxed
50
+ *
51
+ * @return string|void
52
+ *
53
+ * @throws LoaderError
54
+ * @throws SecurityError
55
+ */
56
+ public function twig_include(Environment $env, $context, $template, $variables = array(), $withContext = true, $ignoreMissing = false, $sandboxed = false)
57
+ {
58
+ try {
59
+ return \twig_include($env, $context, $template, $variables, $withContext, $ignoreMissing, $sandboxed);
60
+ } catch (SecurityError $e) {
61
+
62
+ // devではエラー画面が表示されるようにする
63
+ $app = \Eccube\Application::getInstance(array('output_config_php' => false));
64
+ if ($app['debug']) {
65
+ throw $e;
66
+ } else {
67
+ // ログ出力
68
+ log_warning($e->getMessage(), array('exception' => $e));
69
+
70
+ // 例外がスローされた場合、sandboxが効いた状態になってしまうため追加
71
+ $sandbox = $env->getExtension( '\Twig\Extension\SandboxExtension');
72
+ if (!$sandbox->isSandboxedGlobally()) {
73
+ $sandbox->disableSandbox();
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }

問い合わせ先

本脆弱性に関するお問合せ:

EC-CUBE 運営チーム
MAIL: support@ec-cube.net

謝辞

本脆弱性は、

よりご報告いただきました。
この場をお借りして、厚く御礼申し上げます。