Overview
HTTPセキュリティヘッダーとは、WebサーバーがHTTPレスポンスに付与する特別なヘッダーで、ブラウザに対してセキュリティに関する動作指示を与えるものです。適切に設定することで、XSS(クロスサイトスクリプティング)、クリックジャッキング、MIMEタイプスニッフィング、プロトコルダウングレード攻撃など、さまざまなWebアプリケーション攻撃からユーザーを保護できます。
セキュリティヘッダーは多層防御(Defense in Depth)の考え方に基づく重要な防御層です。アプリケーションコード自体にセキュリティ上の問題がなくても、セキュリティヘッダーを設定することでブラウザレベルでの追加的な保護を実現できます。逆に、セキュリティヘッダーが適切に設定されていないWebサイトは、攻撃者に余分な攻撃機会を与えてしまいます。
近年では、SecurityHeaders.comやMozilla Observatoryなどの無料ツールを使用して、Webサイトのセキュリティヘッダー設定状況を簡単に評価・スコアリングできます。企業のセキュリティ監査でもセキュリティヘッダーの設定状況は重要な評価項目となっています。
Details
X-Content-Type-Options
X-Content-Type-Options: nosniffは、ブラウザによるMIMEタイプスニッフィング(Content-Typeヘッダーを無視してコンテンツの内容からファイルタイプを推測する動作)を防止するヘッダーです。攻撃者が画像ファイルとしてアップロードしたHTMLファイルが、ブラウザのスニッフィングによりHTMLとして実行されるケースを防ぎます。
設定は非常にシンプルで、すべてのレスポンスに付与するべきセキュリティヘッダーの一つです。副作用もほとんどなく、最優先で導入すべきヘッダーとされています。
X-Frame-Options
X-Frame-Optionsは、Webページがiframeやframeに埋め込まれることを制御するヘッダーです。クリックジャッキング攻撃(透明なiframeを重ねてユーザーに意図しない操作をさせる攻撃)を防止するために使用されます。
- DENY:すべてのフレームへの埋め込みを禁止
- SAMEORIGIN:同一オリジンからの埋め込みのみ許可
- ALLOW-FROM uri:指定したURIからの埋め込みのみ許可(ただし多くのブラウザで非対応のため非推奨)
現在はCSP(Content Security Policy)のframe-ancestorsディレクティブが後継として推奨されていますが、古いブラウザとの互換性のためにX-Frame-Optionsも併用することがベストプラクティスです。
Strict-Transport-Security(HSTS)
HSTS(HTTP Strict Transport Security)は、ブラウザに対して指定された期間中はHTTPS接続のみを使用するよう指示するヘッダーです。これにより、HTTPからHTTPSへのリダイレクト中にSSLストリッピング攻撃(HTTPS接続をHTTPにダウングレードする攻撃)が行われるリスクを排除します。
設定例:Strict-Transport-Security: max-age=31536000; includeSubDomains; preload。max-ageは秒単位で指定し(31536000秒=1年)、includeSubDomainsですべてのサブドメインにもHSTSを適用し、preloadはブラウザのHSTSプリロードリストへの登録申請に必要です。プリロードリストに登録されると、ユーザーが初めてそのサイトにアクセスする場合でもHTTPSが強制されます。
Referrer-Policy
Referrer-Policyは、ページ遷移時にリファラー(参照元URL)情報をどの程度送信するかを制御するヘッダーです。リファラーにはURLパラメータに含まれるセッショントークンや個人情報が含まれる可能性があるため、適切に制限することがプライバシー保護とセキュリティの観点から重要です。
推奨設定はstrict-origin-when-cross-origin(同一オリジンでは完全なURL、クロスオリジンではオリジンのみ、HTTPSからHTTPへはリファラーなし)です。より厳格なno-referrerを設定するとリファラーを一切送信しませんが、アナリティクスの精度に影響する場合があります。
Permissions-Policy
Permissions-Policy(旧Feature-Policy)は、ブラウザの機能(カメラ、マイク、位置情報、全画面表示など)へのアクセスを制御するヘッダーです。自サイトやiframeで埋め込まれたコンテンツがどの機能を使用できるかを明示的に定義します。
設定例:Permissions-Policy: camera=(), microphone=(), geolocation=(self)。この設定ではカメラとマイクへのアクセスを完全に禁止し、位置情報は自サイトのみに許可します。不要な機能を無効化することで、悪意のあるスクリプトによるプライバシー侵害を防ぎます。
X-XSS-Protectionの非推奨化
X-XSS-Protectionは、ブラウザ内蔵のXSSフィルターを制御するためのヘッダーでしたが、現在は非推奨とされています。Chrome、Edge、Firefoxなどの主要ブラウザはXSSフィルター機能を廃止しており、このヘッダーは効果がなくなっています。
さらに、X-XSS-Protection: 1; mode=blockの設定は、特定の条件下で逆にXSS脆弱性を生み出す可能性が指摘されています。現在のベストプラクティスはX-XSS-Protection: 0を設定してXSSフィルターを明示的に無効化し、代わりにCSP(Content Security Policy)で包括的なXSS対策を行うことです。
Security Measures
- 01必須ヘッダーの即時導入:X-Content-Type-Options: nosniff、X-Frame-Options: DENY(またはSAMEORIGIN)、Referrer-Policy: strict-origin-when-cross-originの3つは副作用が少なく、すべてのWebサイトで即座に導入すべきヘッダーです。
- 02HSTSの段階的導入:Strict-Transport-Securityは、まずmax-ageを短い値(例:300秒)で導入してテストし、問題がなければ段階的に延長してください。最終的にincludeSubDomainsとpreloadを追加し、HSTSプリロードリストへの登録を検討しましょう。
- 03CSPとの連携による多層防御:セキュリティヘッダーはCSP(Content Security Policy)と組み合わせることで最大の効果を発揮します。X-Frame-Optionsに加えてCSPのframe-ancestorsを設定し、X-XSS-Protectionの代わりにCSPのscript-srcディレクティブでXSS対策を行ってください。
- 04Permissions-Policyによる機能制限:Webサイトで実際に使用しないブラウザ機能(カメラ、マイク、位置情報、決済API等)はPermissions-Policyで明示的に無効化してください。攻撃者による悪用やサードパーティスクリプトによる不正利用を防止できます。
- 05定期的なヘッダー監査の実施:SecurityHeaders.com、Mozilla Observatory、またはNmapなどのツールを使用して、セキュリティヘッダーの設定状況を定期的に監査してください。CI/CDパイプラインにヘッダーチェックを組み込むことで、設定の退行を防止できます。
- 06Webサーバーレベルでの一括設定:セキュリティヘッダーはアプリケーションコードではなく、Webサーバー(Nginx、Apache)やリバースプロキシ(Cloudflare、AWS CloudFront等)のレベルで一括設定することを推奨します。これにより、すべてのレスポンスに確実にヘッダーが付与され、設定の管理も容易になります。
Incidents
📋 X-Frame-Options未設定によるクリックジャッキング被害
複数のオンラインバンキングサービスにおいて、X-Frame-Optionsヘッダーが設定されていなかったために、クリックジャッキング攻撃による不正送金被害が発生しています。攻撃者は正規のバンキングサイトをiframeに埋め込み、その上に透明なボタンを重ねることで、ユーザーが気づかないうちに送金操作を実行させました。
被害者は一見すると無害なWebサイトでゲームやアンケートに回答しているつもりでしたが、実際にはバンキングサイトの「送金確認」ボタンをクリックさせられていました。X-Frame-Options: DENYまたはSAMEORIGINを設定するだけで、このような攻撃を完全に防止できたケースです。
📋 HSTS未設定による中間者攻撃(SSLストリッピング)
公共Wi-Fi環境を利用するユーザーを標的としたSSLストリッピング攻撃が、HSTSを導入していないWebサイトで複数報告されています。攻撃者はARP偽装やDNSスプーフィングによって中間者ポジションを確保し、HTTPSリクエストをHTTPにダウングレードすることで通信内容を傍受しました。
HTTPからHTTPSへの301リダイレクトのみに頼っていたWebサイトでは、初回のHTTPリクエスト時に攻撃者がリダイレクトを阻止し、HTTPのままユーザーに偽のページを表示しました。HSTSを導入しHSTSプリロードリストに登録していれば、ブラウザが自動的にHTTPS接続を強制するため、この攻撃は防止できました。
📋 Content-Type スニッフィングを悪用した攻撃
ファイルアップロード機能を持つWebアプリケーションにおいて、X-Content-Type-Options: nosniffが設定されていなかったために、MIMEタイプスニッフィングを悪用した攻撃が発生しました。攻撃者はJavaScriptコードを含むファイルを画像ファイル(.png)として偽装してアップロードしました。
サーバーはContent-Type: image/pngとしてファイルを配信しましたが、X-Content-Type-Optionsヘッダーが未設定だったため、一部のブラウザがファイル内容をスニッフィングしてHTMLとして解釈し、埋め込まれたJavaScriptが実行されました。この結果、他のユーザーのセッションCookieが窃取される被害が発生しました。