クロスサイトスクリプティング(XSS)
Cross-Site Scripting (XSS)
攻撃者のJavaScriptを他のユーザーのブラウザで実行させる攻撃。Cookie窃取やなりすましに使われる。根本対策は『出力時のエスケープ』とCSP。OWASPでは A03 Injection に分類される。
XSSとは何か(たとえ話)
**XSS(Cross-Site Scripting)**は、攻撃者が書いたJavaScriptを、他の人のブラウザで勝手に実行させる攻撃です。
たとえ話: 掲示板に『コメント』を書ける機能があるとします。普通の人は『いい記事ですね』と書きます。でも攻撃者は、コメント欄にスクリプトそのものを書き込みます。サイトがそれをそのまま表示すると、その掲示板を見た全員のブラウザで攻撃者のスクリプトが動いてしまう。これがXSSです。コメントという『データ』であるべきものが、ブラウザに『プログラム』として解釈されてしまうのが問題の本質です。
スクリプトが動くと、被害者のログインCookieを盗んで攻撃者に送る、勝手に操作する、偽のログイン画面を出す、といったことが可能になります。
3つの種類
図を描画中...
- Stored(蓄積型): スクリプトがDBに保存され、そのページを見た全員に配信される。掲示板・プロフィール欄など。被害が最も広い。
- Reflected(反射型): URLパラメータなどの入力が、そのページに即座に反射されて実行される。攻撃者が罠URLを踏ませる必要がある。
- DOM-based: サーバではなくブラウザ側のJavaScriptが、入力を安全でない方法でページに書き込むことで起きる。
防御: 『出力エスケープ』が主役
一番のポイント: 入力を受け取る時ではなく、画面に出力する時にエスケープする。
エスケープとは、<script> のような特殊文字を <script> のような『ただの文字』に変換して、ブラウザにプログラムとして解釈させないこと。これで攻撃者の文字列は『画面に表示されるただのテキスト』になり、実行されません。
ただし注意。出力する場所(コンテキスト)によって正しいエスケープが違います:
| 出力場所 | 必要なエスケープ |
|---|---|
| HTML本文 | HTMLエスケープ(< → <) |
| HTML属性の中 | 属性用エスケープ(引用符の扱いに注意) |
<script> の中 | JavaScript用エスケープ |
| URLの一部 | URLエンコード |
手作業は危険なので、フレームワークの自動エスケープ(React/Vue/テンプレートエンジン等は既定でエスケープする)に乗るのが現実的です。
防御: CSPという二段目の盾
**CSP(Content Security Policy)**は、HTTPヘッダで『このページで実行してよいスクリプトの出所はここだけ』と宣言する仕組みです。たとえ攻撃者がスクリプトを注入できても、CSPが『そのスクリプトは許可リストにない』と弾いてくれる——多層防御の二段目です。
つまずきポイント
- 対策は『入力サニタイズ』だけでは不十分。入力時点では『どこに出力されるか』が分からないため、確実なのは出力時のエスケープ。両方やるのが理想。
- CookieにHttpOnlyを付けると、たとえXSSされてもJavaScriptからCookieを読めなくなる(=トークン窃取を防げる)。これがJWTを localStorage より HttpOnly Cookie に置くべき理由(localStorageはXSSで丸見え)。
- XSSとCSRFを混同しない。XSSは『攻撃者のスクリプトを実行させる』、CSRFは『被害者になりすまして偽リクエストを送らせる』。別物です(CSRFは次項)。
📊 図解
XSS 攻撃の流れ(シーケンス図)
攻撃者が悪意スクリプトを注入し、被害者のブラウザで実行されて Cookie が盗まれます。
図を描画中...
防御後の流れ(出力エスケープで無害化)
出力時にエスケープすれば、スクリプトはただの文字列として表示されるだけです。
図を描画中...