仕組みから学ぶ Web
応用読了目安 15#CSP#HSTS#セキュリティヘッダ#XSS#クリックジャッキング

セキュリティヘッダ — 最後の1枚を、ブラウザに張らせる

XSS は塞いだつもりだった。広告タグの1つが改ざんされ、そこから入力欄の値が外部へ送られた。自前のコードは1行も侵されていない。

この記事の進み方

What — セキュリティヘッダは「ブラウザへの指示」

セキュリティヘッダは、サーバーがブラウザに対して制約を宣言する仕組みです。アプリ側で何かを検査するのではなく、ブラウザに禁止させます

Compare主なヘッダと、防ぐもの

どこから読み込んでよいか、どこへ送ってよいかを制限する。

Content-Security-Policy:
default-src 'self';
script-src 'self' cdn.example.com;
connect-src 'self' api.example.com;
frame-ancestors 'none'
防ぐもの
XSS の実行・情報の持ち出し
導入の手間
大きい
壊れやすさ
間違えると画面が壊れる
  • connect-src が効けば、冒頭の事故で外部への送信を止められた。
  • report-only モードで、壊さずに違反だけ集められる。
  • インラインの script を禁じるため、既存サイトへの後付けは手間がかかる。

どれも「最後の1枚」であって、これだけで守るものではない。本体の対策があったうえで、間違えたときの被害を小さくする。

CSP
Content Security Policy。読み込み元と送信先をブラウザに制限させる仕組み。
report-only
違反を報告するだけで、実際にはブロックしないモード。導入の下見に使う。
nonce
リクエストごとに変わる使い捨ての値。これを持つ script だけを許可する。
HSTS
HTTP Strict Transport Security。HTTPS での接続を強制する指示。
クリックジャッキング
透明な iframe に重ねて、利用者に意図しない操作をさせる攻撃。

CSP が防ぐのは「実行」と「持ち出し」の両方

CSP は2方向を制限できます。

  • script-src — どこから読み込んだスクリプトを実行してよいか
  • connect-src — どこへ通信してよいか

冒頭の事故では、読み込みは許可していたドメインから攻撃が来ました。script-src では止まりません。

しかし connect-src が効いていれば、外部への送信が止まります。盗んだ値を持ち出せなければ、被害はほぼ出ません。

「入られる」と「持ち出される」は別の段階で、それぞれに守りを置けます。

Why — アプリの対策だけでは、届かない範囲がある

自分が書いていないコードは、レビューできない

<script src="..."> で読み込む外部のコードは、中身がいつでも差し替わります

レビューした時点のコードと、利用者のブラウザで実行されるコードが同じである保証はありませんsecurity/supply-chain)。

広告、解析、チャットのウィジェット、A/B テスト。これらは全部、こちらのページで、こちらの権限で動きます。

エスケープは「入力の対策」でしかない

XSS 対策のエスケープは、利用者の入力が HTML として解釈されるのを防ぐものです。

冒頭の事故には利用者の入力が関与していません。攻撃者は正規の <script> タグを使いました。 エスケープでは触れられない経路です。

Figure攻撃が通る経路と、守りの位置
  1. 1利用者の入力
  2. 2自社のコード
  3. 3外部のスクリプト
  4. 4外部への送信
1/4
利用者の入力エスケープ・バリデーションで守る。アプリ側でできる

アプリ側の対策は左側にしか置けない。右側(読み込んだコードが何をするか)は、ブラウザに制限させるしかない。

「効いているか」が見えにくい

セキュリティヘッダの厄介なところは、設定しても何も起きないことです。

正しく設定されていれば何も起きず、設定されていなくても何も起きません。攻撃が来るまで差が出ない。

だから「設定したつもり」が放置されます。タイプミスで無効なヘッダになっていても、誰も気づきません。

演習 — まず自分で判断する

確認 — ここまで読めたか

冒頭の事故で、被害を防げた可能性が最も高い設定はどれですか?

まず選ぶ(解答例は a〜d の記号で説明します)

確認 — ここまで読めたか

HSTS を `max-age=31536000; includeSubDomains` で設定しました。注意すべきことは何ですか?

まず選ぶ(解答例は a〜d の記号で説明します)

読み終わりましたか?

読了にすると、これを前提とする記事がロードマップで開放されます。