LaravelのXSS対策の仕組み [ XSSとは? ]
環境、対象
- Laravel5.6
- PHP7
要点
記事にする理由
- 仕事でXSS周りの不具合修正の対応を行った際に知ったことを忘れないため!
内容
XSSとはなにか?
- 一言で言うと、投稿の際など入力欄に、jsコードやhtmlタグを入力して行うサイトへの攻撃のことです。
なぜ問題なのか
- 一例ですが、入力フォームにjsコードを書かれ、XSS対策をしないまま出力するとコードが実行されてしまいます。
入力フォームに↓を入力したとします。
入力欄 「<script> window.alert('このメッセージを表示したユーザーに、アラートメッセージが表示されてしまう'); </script>」
このようにalertを入力されるとそのページにアクセスした人全員にjsのalerメッセージtが表示されるようになるといった状態になります。 (alertを無限実行などされたら困りますね。)
原因
- viewへの出力時に、エスケープしていないこと
viewで入力内容を出力する際に、エスケープをしていないことから、入力内容にhtmlやjsが含まれていたらそれをそのままコードとして受け取り、 内容を実行してしまいます。
そこで、出力時にエスケープをかけてあげることでコードとしてではなく、文字列としてタグを受け取ってくれるので上記のように、alertが実行されるようなことは無くなります。
解決策
- viewの出力箇所を {{ }} でくくってあげることで解消、対策が自動的に行われます。
これはLavravelのviewであるbladeの仕組みで、コントローラから受け取ったデータを出力する際に {{ $message }}のように出力すると、自動的にhtmlentites関数をかけた後に出力してくれるので、XSS対策を行うことができます。つまり、先ほどのalertも実行がされずに出力されるようになります。
コントローラー
$message = "<script> window.alert('hoge'); </script>"
ブレード(View)
メッセージ:{{ $message }}
このように書いてあげると、自動的にタグは文字列として変換されるのでXSS対策が行われるということになります。
また、XSS対策を行わずにむしろタグなどをそのまま実行して表示してしまいたい場合には、
{!! $message !!}
このように書いてあげると、そのままタグをタグとして実行してくれます。
おさらい
ひとこと
- Laravelでは {{ }}で出力を基本はせざるを得ないので意識しなくても大丈夫だと思いますが、ただ意識しなくて良いがゆえにあまり理解しようともせず、モヤモヤする部分となりがちだとおもいますので、これを機会に少しずつ覚えていただければと思います!
Laravelの日本語公式ドキュメントの閲覧バージョンを指定すると、 該当バージョンへ自動遷移してくれるChromeアプリを作成したので、ぜひ!