セキュリティヘッダー完全ガイド
このドキュメントの目的
Webアプリケーションを保護するためのHTTPセキュリティヘッダーを理解し、ID/認証システムでの適切な設定方法を学びます。
セキュリティヘッダー一覧
| ヘッダー | 目的 | 重要度 |
|---|---|---|
| Strict-Transport-Security | HTTPS強制 | ◎ 必須 |
| Content-Security-Policy | XSS対策 | ◎ 必須 |
| X-Content-Type-Options | MIMEスニッフィング防止 | ◎ 必須 |
| X-Frame-Options | クリックジャッキング防止 | ○ 推奨 |
| X-XSS-Protection | ブラウザXSSフィルタ | △ レガシー |
| Referrer-Policy | リファラー情報制御 | ○ 推奨 |
| Permissions-Policy | ブラウザ機能制限 | ○ 推奨 |
| Cache-Control | キャッシュ制御 | ◎ 必須 |
HSTS (HTTP Strict Transport Security)
目的
ブラウザにHTTPS接続を強制し、中間者攻撃を防止。
設定例
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
パラメータ解説
| パラメータ | 説明 | 推奨値 |
|---|---|---|
| max-age | HTTPS強制期間(秒) | 31536000(1年) |
| includeSubDomains | サブドメインにも適用 | 有効化推奨 |
| preload | ブラウザプリロードリストに登録 | 慎重に検討 |
段階的導入
# Step 1: 短い期間でテスト(5分)
Strict-Transport-Security: max-age=300
# Step 2: 期間を延長(1週間)
Strict-Transport-Security: max-age=604800
# Step 3: 本番設定(1年)
Strict-Transport-Security: max-age=31536000; includeSubDomains
注意点
⚠️ HSTSの注意点:
- 一度設定すると、max-age期間中はHTTP接続不可
- 証明書の問題があるとサイトにアクセスできなくなる
- preloadは取り消しが困難(数ヶ月かかる)
CSP (Content-Security-Policy)
目的
XSS(クロスサイトスクリプティング)攻撃を防止。許可されたリソースのみ読み込み可能に。
基本構文
Content-Security-Policy: directive-name 'value' source-list;
主要ディレクティブ
| ディレクティブ | 制御対象 |
|---|---|
| default-src | デフォルトのリソース |
| script-src | JavaScript |
| style-src | CSS |
| img-src | 画像 |
| font-src | フォント |
| connect-src | XHR/Fetch/WebSocket |
| frame-src | iframe |
| frame-ancestors | 自サイトをiframeで埋め込めるサイト |
| form-action | フォーム送信先 |
| base-uri | base要素のURL |
ソース値
| 値 | 意味 |
|---|---|
| 'none' | 何も許可しない |
| 'self' | 同一オリジンのみ |
| 'unsafe-inline' | インラインスクリプト/スタイル(非推奨) |
| 'unsafe-eval' | eval()等(非推奨) |
| 'nonce-xxx' | 特定のnonceを持つ要素のみ |
| 'strict-dynamic' | nonceで許可されたスクリプトからの読み込みを許可 |
| https: | HTTPSのみ |
| data: | data: URI |
ID/認証システム向け推奨設定
Content-Security-Policy:
default-src 'self';
script-src 'self' 'nonce-{random}';
style-src 'self' 'nonce-{random}';
img-src 'self' data:;
font-src 'self';
connect-src 'self';
frame-ancestors 'none';
form-action 'self';
base-uri 'self';
upgrade-insecure-requests;
レポートモード
本番適用前にテスト:
Content-Security-Policy-Report-Only:
default-src 'self';
report-uri /csp-violation-report;
X-Content-Type-Options
目的
ブラウザのMIMEタイプスニッフィングを防止。
攻撃シナリオ
1. 攻撃者がJavaScriptを含むファイルをアップロード(拡張子は.txt)
2. サーバーがContent-Type: text/plainで配信
3. ブラウザがコンテンツを解析し、JavaScriptとして実行
4. XSS攻撃成功
設定
X-Content-Type-Options: nosniff
効果
- ブラウザはContent-Typeヘッダーを厳密に解釈
- text/plainのファイルをJavaScriptとして実行しない
X-Frame-Options
目的
クリックジャッキング攻撃を防止。
攻撃シナリオ
1. 攻撃者が悪意のあるサイトを作成
2. 透明なiframeで銀行サイトを埋め込む
3. ユーザーは見えているボタンをクリック
4. 実際には銀行サイトの「送金」ボタンをクリック
設定オプシ ョン
# 全てのiframe埋め込みを禁止
X-Frame-Options: DENY
# 同一オリジンからの埋め込みのみ許可
X-Frame-Options: SAMEORIGIN
CSPとの関係
# CSPのframe-ancestorsがより新しい方式
Content-Security-Policy: frame-ancestors 'none'
# 互換性のため両方設定することを推奨
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'