もくじ
したいこと(=タイトル)
タイトルの通りなんですが、改行コード(\n
)は認識させたいけど、HTMLタグ(<scrip>
タグなど)は文字列とて認識させたい!!ってことです。
なぜこれをするかというと、XSS(クロスサイトスクリプティング)攻撃のターゲットにならないための対策です。
では次の変数の中身を出力させて確認してみます。
$data = "明日は\n運動会<br>です。<script>alert('スクリプト実行');</script>";
これを単純に表示すると下記のようになります。
<p>{{ $data }}</p>
それでは順番に見ていきます!
{!! !!}
でHTMLタグをエスケープさせない
{!! !!}
で囲むことでHTMLタグがエスケープされません。
$data = "明日は\n運動会<br>です。<script>alert('スクリプト実行');</script>";
<p>{!! $data !!}</p>
入力フォームにもしHTMLタグを入力された場合それをそのままHTMLタグとして読み込みます。
そのため、変数の中にあるスクリプトが実行してしまいます。また、スクリプト部分はスクリプトとして認識されるので出力もされず文字列だけが出力されます。
その上、\n
はタグではないので改行とは認識されず、<br>
は認識され改行されています。
nl2br関数で\n
を<br>
に変換
$data = "明日は\n運動会<br>です。<script>alert('スクリプト実行');</script>";
<p>{!! nl2br($data) !!}</p>
スクリプトは実行されてしまいましたが、\n
が<br>
に変換され改行して欲しいところですべて改行されていますね。
では次がようやく、本題です!
e()
でサニタイズ
XSSを防ぎながら改行を表示するにはe()
を使って以下のように記述します。
$data = "明日は\n運動会<br>です。<script>alert('スクリプト実行');</script>";
<p>{!! nl2br(e($data)) !!}</p>
スクリプトは実行されず、改行コードで改行もされています。しかし、<br>
もHTMLタグとして認識されるので改行されません。
解説
e()
関数でまずHTMLタグを文字列にします。
<p>{!! e($data) !!}</p>
次に全体をnl2br
関数に入れ、\n
を改行させます。
<p>{!! nl2br(e($data)) !!}</p>
もし囲う順番を間違えると違う結果になります。
<p>{!! e(nl2br($data)) !!}</p>
使い分け
今回取り上げた方法を使って、その時に最適な記述をしましょう。