📌 結論:3つの方法でセキュリティヘッダーを追加できる
コード不要!
設定画面でポチポチするだけ
🏨 ホテルの「標準セキュリティ」
複雑なロジックも可能
レイテンシ:やや大きい
🏨 ホテルの「専属コンシェルジュ」
シンプルな変換向き
レイテンシ:最小
🏨 ホテルの「自動ドア」
🏨 HTTPセキュリティヘッダーとは?
🏨 高級ホテルの「セキュリティバッジ」で理解しよう!
(ブラウザ)
「ページをください」
(Webページ)
「安全なルール」が添付
🎯 HTTPセキュリティヘッダー = ホテルの「セキュリティルール書」
🔐 主要なセキュリティヘッダー6選
「当ホテルは正面玄関(HTTPS)からのみ入館可能です。裏口(HTTP)は使用禁止!」
「部屋に持ち込める荷物は、指定の業者からのみ!不審な荷物は受け取り拒否!」
「荷物のラベルを信用せよ!中身を勝手に開けて確認するな!(偽装防止)」
「当ホテルの写真を他のパンフレットに無断掲載禁止!(偽ホテル対策)」
「不審な動きをする宿泊客は、警備員が自動検知して退去させます!」
「宿泊客がどこから来たかは、必要最小限しか外部に伝えません(プライバシー保護)」
🔄 セキュリティヘッダー追加の流れ
CloudFrontでヘッダーが追加されるタイミング
(S3/ALB等)
付きレスポンス
レスポンス
💡 ポイント:セキュリティヘッダーはレスポンス時に追加される
オリジン(S3等)を変更せず、CloudFrontだけで対応可能!
⚙️ 3つの方法を詳しく解説
🛠️ どの方法を選ぶべき?
✅ メリット
- ✨ コード不要(GUI設定のみ)
- ✨ AWS管理のプリセットあり
- ✨ レイテンシ影響なし
- ✨ 追加コストなし
- ✨ メンテナンス不要
⚠️ デメリット・制限
- ⚠️ 動的な値設定は不可
- ⚠️ 複雑な条件分岐は不可
- ⚠️ カスタムロジックは不可
🎯 こんな場合におすすめ:
「標準的なセキュリティヘッダーを追加したい」「とにかく簡単に設定したい」
→ 90%以上のケースでこれを選べばOK!
✅ メリット
- ✨ 完全なカスタマイズ可能
- ✨ 動的な値の設定OK
- ✨ 複雑な条件分岐OK
- ✨ 外部API呼び出し可能
- ✨ Node.js / Pythonで記述
⚠️ デメリット・制限
- ⚠️ コード記述が必要
- ⚠️ レイテンシが追加される
- ⚠️ 追加コストがかかる
- ⚠️ us-east-1でのみ作成可能
- ⚠️ メンテナンスが必要
exports.handler = async (event) => { const response = event.Records[0].cf.response; const headers = response.headers; // セキュリティヘッダーを追加 headers['strict-transport-security'] = [{ key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubdomains' }]; headers['x-content-type-options'] = [{ key: 'X-Content-Type-Options', value: 'nosniff' }]; headers['x-frame-options'] = [{ key: 'X-Frame-Options', value: 'DENY' }]; return response; };
✅ メリット
- ✨ Lambda@Edgeより高速
- ✨ コストが安い(1/6程度)
- ✨ どのリージョンでも作成可
- ✨ シンプルな処理に最適
⚠️ デメリット・制限
- ⚠️ JavaScriptのみ
- ⚠️ 実行時間1ms以下制限
- ⚠️ メモリ2MB制限
- ⚠️ ネットワークアクセス不可
- ⚠️ 外部ライブラリ使用不可
function handler(event) { var response = event.response; var headers = response.headers; // セキュリティヘッダーを追加 headers['strict-transport-security'] = { value: 'max-age=31536000; includeSubdomains' }; headers['x-content-type-options'] = { value: 'nosniff' }; headers['x-frame-options'] = { value: 'DENY' }; return response; }
📊 3つの方法を比較
🔍 どれを選ぶべき?完全比較表
| 比較項目 | 📋 Response Headers Policy | λ Lambda@Edge | ⚡ CloudFront Functions |
|---|---|---|---|
| 🎯 難易度 | ⭐ 超簡単 | ⭐⭐⭐ 難しい | ⭐⭐ 普通 |
| 💻 コード記述 | ✅ 不要 | ❌ 必要 | ❌ 必要 |
| ⚡ レイテンシ | ✅ なし | ❌ 数ms追加 | ⚠️ 微小 |
| 💰 追加コスト | ✅ なし | ❌ あり | ⚠️ 少額 |
| 🔧 カスタマイズ | ⚠️ 限定的 | ✅ 完全自由 | ⚠️ 制限あり |
| 🔄 動的な値 | ❌ 不可 | ✅ 可能 | ✅ 可能 |
| 🌐 外部API呼出 | ❌ 不可 | ✅ 可能 | ❌ 不可 |
| 🏆 おすすめ度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
📝 Response Headers Policyの設定手順
🚀 5ステップで完了!(推奨方法)
CloudFrontコンソールを開く
AWSマネジメントコンソール → CloudFront → 対象のディストリビューションを選択
Behaviorを編集
「Behaviors」タブ → 編集したいBehaviorを選択 → 「Edit」をクリック
Response Headers Policyを選択
「Response headers policy」セクションで、AWS管理ポリシーまたはカスタムポリシーを選択
おすすめ:「SecurityHeadersPolicy」(AWS管理)
設定を保存
「Save changes」をクリックして設定を保存
完了!🎉
デプロイ完了後(数分)、レスポンスにセキュリティヘッダーが追加されます
⚠️ ベストプラクティス
🎯 セキュリティヘッダー設定の注意点
🔒 HSTSは慎重に
max-ageを長くしすぎると、HTTPに戻せなくなる。まずは短い値(86400=1日)でテストしてから延長。
📜 CSPは段階的に
最初は「Content-Security-Policy-Report-Only」でテスト。いきなり本番適用すると、サイトが壊れる可能性あり。
🧪 ステージング環境でテスト
本番適用前に必ずステージング環境でテスト。SecurityHeaders.comなどのツールで確認。
📊 モニタリングを忘れずに
CloudWatch Logsでエラーを監視。CSP違反レポートを収集して、問題を早期発見。
❓ よくある質問
S3自体にはセキュリティヘッダーを設定する機能がありませんが、CloudFrontのResponse Headers Policyを使えば、S3から配信するコンテンツにもセキュリティヘッダーを追加できます。これがCloudFrontを使う大きなメリットの1つです。
Response Headers Policyでは、オリジンのヘッダーを「上書き」するか「維持」するかを選択できます。Lambda@EdgeやCloudFront Functionsでは、コードで自由に制御可能です。
• X-Content-Type-Options: nosniff
• X-Frame-Options: SAMEORIGIN
• X-XSS-Protection: 1; mode=block
• Strict-Transport-Security: max-age=31536000
• Referrer-Policy: strict-origin-when-cross-origin
より厳格な設定が必要な場合は、カスタムポリシーを作成してください。
🎓 まとめ
コード不要
90%のケースでこれでOK
複雑なロジック向け
外部API連携も可能
シンプルな処理向け
コスト効率◎