概要
Webアプリケーションの出力処理に脆弱性があると、
攻撃者にHTML内に悪意のあるスクリプトを埋め込まれる。
ユーザーのブラウザ上でスクリプトを実行させ、
出力されたその情報を盗み取る(攻撃者のサーバーに送信させるなど)攻撃。
- Cookieを使ってログインのセッション管理をしているサイトは特に注意する。
ユーザーにスクリプトを送信させる方法
- 反射型:悪意のあるメール等のURLをユーザーがクリックしたとき
- 格納型:掲示板などでスクリプト付きの投稿をユーザーにさせて、他のユーザーが閲覧したとき
- DOM型:javascriptの脆弱性を狙う
発生しうる脅威
フィッシング詐欺による重要情報の漏洩
本物のWebサイト上に偽のフォームが表示され、ユーザーが入力した個人情報が盗まれる。Cookie情報の漏洩
Cookieに格納されていた個人情報やセッションIDが盗まれ、 セッションハイジャックによるなりすまし、不正アクセスにつながる。ブラウザに任意のCookieを保存させられる
攻撃者がユーザーのブラウザにあるCookieを、Set-Cookieヘッダを使って書き換える。
セッションIDの固定化攻撃につながる。偽情報の流布による混乱
原因
対策
根本的解決
1.すべての出力要素にエスケープ処理をする
- 特別な意味を持つ文字をHTMLエンティティへ変換し、無害化(サニタイジング)する。
- HTMLタグを出力するときは、属性値を必ずダブルクォートでくくる。
- すべての出力に対して処理を行うが、ユーザーからの入力、データベースやファイルから読み込んだ文字列、演算によって生成した文字列等に特に注意する。
$keyword = param('keyword'):
print "<input value="$keyword">”
↓
print "<input value=\"" . htmlspecialchars($keyword, ENT_QUOTES). "\">";
☀︎PHPのhtmlspecialchars()は、
スクリプトの構成に必要な特殊文字(&,<,>,”,’)を、(&:, <, >, " ')へ置換する関数。
「ENT_QUOTES」と指定すると、"と'の両方がエスケープされる。
2.「http://」「https://」で始まるURLのみ許可する
- href, rel, src などの属性値にユーザからの入力を使うとき、「javascript:」から始まるスクリプトを埋め込まれてしまう。
3.文字コードの指定する
- ブラウザは受け取ったHTMLを指定した文字コードで解釈する。
① HTTPレスポンスヘッダの「Content-Type」フィールドに、「charaset=UTF-8」と指定する
② HTMLのMETA宣言に、「charaset=UTF-8」と指定する
③設定など外部リソースを指しているファイルにも文字コードを指定する
保険的対策
4.Cookieの発行時にHttpOnly属性をつける
5.ユーザーからの入力値を制限する
XSS攻撃ではリンク等を踏ませるため、入力側のバリデーションを経由することはないが、
入力値のバリデーションで不正な入力を排除することができ、
攻撃のリスクを減らすことはできる。ホワイトリスト方式を使う
その引数に許可する文字の組み合わせを決めておき、それ以外は許可しない方式。 郵便番号の入力なら、数字以外の入力を許可しない。 他にも入力値の長さ制限をつけることで、攻撃が可能となるスクリプトの挿入を抑制することもできる。出力の文字列は削除ではなく、無害化(サニタイジング)で置換するようにする。 削除したことにより、スクリプト文字列を形成してしまう。
Laravelでの実装例
1. {{ }}で囲みエスケープ処理をする
出力する変数を{{ $変数名 }}と囲むだけで、自動的にPHPのhtmlspecialchars関数を通されエスケープ処理をしてくれる。
エスケープ処理をしたくないときは、{!! $変数名 !!}と囲む。非推奨
ビューのblade.phpファイルに
<body class="antialiased"> @auth <p> {{ Auth::user()->name }}さん、こんにちは。 </p> @endauth </body>
☀︎ログイン中のユーザーの名前を表示している。
- @authディレクティブで、ログイン済みユーザーだけに表示している。