🕌

Laravel EC-CUBEの脆弱性から学ぶ、改行コードを改行タグに変換する方法

2021/05/10に公開

前置き

EC-CUBEで、危険度「高」のXSSの脆弱性が発見され、既に被害も出ているようです。
修正方法から判断すると、管理画面のテンプレで、HTMLが有効になってしまっていたようです。
https://www.ec-cube.net/info/weakness/20210507/#diff

変更前
{{ form.tpl_data.vars.data|trans|raw|nl2br }}
変更後
{{ form.tpl_data.vars.data|trans|nl2br }}

開発者としては、うっかり、raw を入れてしまい、その後そのままになってしまった、という感じでしょうか。

これは、Laravelで書く場合、

{!! nl2br(e($content)) !!}

という書き方になるのでしょうが、よくよく考えてみると、この書き方もうっかり「e」を書き損ねると、EC-CUBEと同様の脆弱性になりかねません。

ではどうする?

回答は、@ucan-lab さんが示してくれています。
https://qiita.com/ucan-lab/items/4e17bdef22d7cd8a3429

これを使ってやれば、そんなミスも無くなります。
解説は省かれていますが、HtmlString を返しているので、{{ }} の記法でも意図した通りに動作します。これで万々歳ですね。

ですが、これで終わってしまうと記事のオリジナルティが無くなってしまうので、
@ucan-lab さんのが一番ベストな方法ではありますが、敢えて別の選択肢も模索してみます。

Blade カスタムディレクティブ

ということで、Blade カスタムディレクティブを使った方法です。
AppServiceProvider の boot() 内に、以下の感じで書きます。

    public function boot()
    {
        \Blade::directive('safeBr', function ($expression) {
            return "<?php echo nl2br(e($expression)) ?>";
        });
    }

で、テンプレ側では以下の感じで呼び出します。

@safeBr($content)

あくまで1つの選択肢という事で。

ちなみに、カスタムディレクティブは、カナダ LOVE な CONSOLE DOT LOG さんのブログにある通り、キャッシュ問題がありますのでご注意下さい。
https://blog.capilano-fw.com/?p=2804

Discussion