要望や症状
商品登録画面のフリーエリアでTwig構文を使用した画像パスを入力すると、保存時に構文がHTMLエスケープされてしまい、意図した表示にならない問題が発生します。
エスケープの具体例
入力時の構文:
<img src="{{ asset('assets/img/product/hoge/hogehoge.png','user_data') }}" alt="hogehoge" />
保存後の構文:
<img src="%7B%7B%20asset('assets/img/product/hoge/hogehoge.png','user_data')%20%7D%7D" alt="hogehoge" />
問題が発生する条件
この問題は、商品登録画面のフリーエリアにTwig構文(asset()関数など)を含むHTMLを入力して「登録」ボタンを押した際に発生します。保存時にデータベースのdtb_productテーブルのfree_areaカラムで構文がエスケープされてしまいます。
なお、通常のTwig変数({{ BaseInfo.delivery_free_amount|number_format(0, '.', ',') }}など)については正常に保存され、表示時にも適切に動作します。
理由や原因
この問題の原因は、EC-CUBE 4系の商品フリーエリアでHTMLPurifierによるサニタイズ処理が実行される際に、Twig構文の二重波括弧({{}})がHTMLエスケープ処理の対象として認識されてしまうことにあります。
技術的な背景
ProductTypeクラスでは、free_areaフィールドに対して'purify_html' => trueがデフォルトで設定されています。HTMLPurifierはセキュリティ上の観点から、未知の構文や潜在的に危険と判断される記述をエスケープする仕組みになっているため、Twig構文も処理対象となってしまいます。
一方で、既存のTwig変数が正常に動作するのは、HTMLPurifierの設定や処理タイミングが異なることが理由として考えられます。
解決策
解決方法1:相対パスでの記述(推奨)
最も安全で確実な解決方法は、Twig構文を使用せず、直接相対パスを記述することです。この方法であれば、HTMLPurifierの処理に影響されることなく、確実に画像を表示できます。
<img src="html/user_data/assets/img/product/hoge/hoge.png" alt="hogehoge" />
解決方法2:HTMLPurifierの無効化(セキュリティリスクあり)
どうしてもTwig構文を使用したい場合は、CustomizeディレクトリでForm Extensionを作成してHTMLPurifierを無効化することで対応できます。ただし、この方法にはセキュリティ上のリスクが伴うため、十分に検討した上で実装してください。
Form Extension の使用
// app/Customize/Form/Extension/Admin/ProductTypeExtension.php
<?php
namespace Customize\Form\Extension\Admin;
use Eccube\Form\Type\Admin\ProductType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
class ProductTypeExtension extends AbstractTypeExtension
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('freearea', TextareaType::class, [
'label' => 'admin.product.freearea',
'required' => false,
'purify_html' => false,
]);
}
public static function getExtendedTypes(): iterable
{
return [ProductType::class];
}
}
セキュリティに関する重要な注意事項
解決方法2を採用する場合は、以下のセキュリティリスクが存在することを理解した上で実装する必要があります。
- XSS(クロスサイトスクリプティング)攻撃のリスクが高まります:悪意のあるスクリプトが実行される可能性があります
- HTMLやJavaScriptの実行リスク:意図しないコードが実行される危険性があります
- 管理権限の適切な管理が必須:管理画面へのアクセス権限を持つユーザーのみが編集可能であることを前提としています
これらのリスクを考慮し、可能な限り解決方法1(相対パス記述)を採用することを強く推奨します。