セキュリティヘッダー:各ヘッダーの役割と設定方法
数個のHTTPレスポンスヘッダーで、クロスサイトスクリプティング、クリックジャッキング、ダウングレード攻撃から訪問者を守れます。各ヘッダーの役割、最初に使える安全な値、無料のセキュリティヘッダーチェッカーによる診断内容、報告された各問題の修正方法を nginx、Apache、Cloudflare 別に解説します。
Searvia · 2026/10/24 · 読了目安:3分

要点: セキュリティヘッダーは、サーバーがすべてのページと一緒に送信する指示です。ブラウザに対して、常にHTTPSを使う、許可した配信元のスクリプトだけを実行する、他サイトによるページのフレーム埋め込みを拒否する、ファイルタイプを推測しない、Referer ヘッダーに完全なURLを含めない、といった動作を求めます。まずサイト全体のHTTPS化と有効な証明書を整え、その上で
Strict-Transport-Security、X-Content-Type-Options: nosniff、Referrer-Policy: strict-origin-when-cross-origin、そしてframe-ancestorsまたはX-Frame-Optionsを追加しましょう。Content-Security-Policyはまずレポートオンリーモードで導入します。これらはすべてサーバーまたはCDNの設定で行います。
セキュリティヘッダーは費用対効果の高い保険です。ほとんどはサーバー設定1行で済み、パフォーマンスへの影響もなく、さまざまな種類の攻撃を防げます。セッションを盗む挿入スクリプト、クリックを誘導する見えないフレーム、カフェのネットワークで訪問者をHTTPにダウングレードする攻撃などです。セキュリティスキャナー、大企業の顧客、セキュリティ質問票が最初に確認する項目でもあります。
このガイドでは、各ヘッダーとその前提となる接続の基本を説明し、安全な初期値を示します。さらに、無料のセキュリティヘッダーチェッカーがサイトをどう診断するか、報告された各問題をどう修正するかを順に見ていきます。
まず基本:HTTPS、証明書、mixed content
ヘッダーは暗号化された接続の上で機能するもので、それがなければ効果がありません。最初に押さえる基本は3つです。
- 全ページでHTTPSを使い、HTTPはリダイレクトする。 2018年7月の Chrome 68 以降、Chrome はすべてのHTTPページを「保護されていない通信」と表示します(Chromium Blog)。Google のページエクスペリエンスに関するガイダンスも「ページは安全な方法で配信されていますか?」と問いかけています。
- 使用するすべてのホスト名をカバーする有効な証明書。
www付きと無しのドメインを含みます。期限切れや不一致の証明書があると、全画面の警告が表示されます。 - mixed content がないこと。 安全なページが
http://でファイルを読み込むと、完全に安全とは言えません。MDN によると、ブラウザーは画像、音声、動画を自動的にHTTPSへアップグレードし、スクリプト、スタイルシート、iframe などの「ブロック対象」コンテンツは完全にブロックします。その結果ページが壊れます。
ヘッダーを1つずつ解説
| ヘッダー | 防ぐもの | 安全な初期値 |
|---|---|---|
Strict-Transport-Security | HTTPへのダウングレード、公共ネットワークでのCookie窃取 | max-age=31536000; includeSubDomains(テスト後) |
Content-Security-Policy | クロスサイトスクリプティング(XSS)、コンテンツ挿入、frame-ancestors によるクリックジャッキング | まず Content-Security-Policy-Report-Only から開始 |
X-Frame-Options または CSP の frame-ancestors | クリックジャッキング | SAMEORIGIN または frame-ancestors 'self' |
X-Content-Type-Options | MIMEスニッフィング:ファイルがスクリプトやスタイルとして実行される | nosniff |
Referrer-Policy | 完全なURLが他サイトに漏れること | strict-origin-when-cross-origin |
Permissions-Policy | 埋め込みスクリプトによるカメラ、マイク、位置情報の利用 | camera=(), microphone=(), geolocation=() |
Strict-Transport-Security(HSTS)
HSTS は、ユーザーが http:// と入力したり古いリンクをクリックしたりした場合でも、指定した秒数のあいだ、そのホストにHTTPSを使うようブラウザーに指示します。MDN は次の3点に注意するよう述べています。
- 通常のHTTPで届いたヘッダーはブラウザーに無視されます。HTTPSのレスポンスで送信してください。HTTPからHTTPSへのリダイレクトには不要です。
- 効果が出るのは最初の安全なアクセスの後です。プリロードがこの隙間を埋めます。
includeSubDomainsはすべてのサブドメインにポリシーを適用するため、事前に全サブドメインを確認してください。
HSTS プリロードリストは、ドメインをブラウザーに直接組み込みます。要件は、有効な証明書、同一ホストでのHTTPからHTTPSへのリダイレクト、全サブドメインのHTTPS対応、そして max-age が31536000以上で includeSubDomains と preload を含むヘッダーです。また「プリロードリストへの登録は簡単には取り消せない」と警告しており、削除がユーザーに反映されるまで数か月かかります。確信が持てるときだけプリロードしましょう。
Content-Security-Policy(CSP)
CSP はヘッダーの中で最も強力ですが、導入は最も難しいものです。スクリプト、スタイル、画像などのリソースを読み込める場所を列挙し、それ以外はブラウザーが拒否します。MDN は、これを主に「クロスサイトスクリプティング(XSS)攻撃に対する防御」と説明しています。
現在推奨される形は、長いドメインの許可リストではなく、nonce やハッシュに基づく strict CSP です。
Content-Security-Policy: script-src 'nonce-{RANDOM}'; object-src 'none'; base-uri 'none'
nonce はランダムで、レスポンスごとに異なる値にする必要があります。MDN は、'unsafe-inline' は「CSP を設定する目的の大部分を無効にしてしまう」と警告しています。
strict なポリシーは、アナリティクスのタグ、チャットウィジェット、インラインスクリプトを壊す可能性があります。そのため2段階で導入します。まず、レポート用エンドポイントを指定して Content-Security-Policy-Report-Only を送信し、レポートで見つかった問題を修正してから、強制適用するヘッダーに切り替えます。CSP には upgrade-insecure-requests(mixed content に対するセーフティネットであり、HSTS の代わりにはなりません)もあり、frame-ancestors でフレーム埋め込みを制御することもできます。
X-Frame-Options と frame-ancestors
クリックジャッキングとは、あなたのページを他サイト上の見えないフレームに読み込み、ボタンをクリックするよう仕向ける攻撃です。防ぐ方法は2つあります。
X-Frame-Options: SAMEORIGIN(またはDENY)。古い方のヘッダーです。ALLOW-FROMは廃止されており、最近のブラウザーではヘッダーごと無視されます。Content-Security-Policy: frame-ancestors 'self'。より柔軟な方法で、特定のパートナーのオリジンを列挙することもできます。
どちらも <meta> タグでは機能しません。MDN は、meta 要素内の X-Frame-Options は「効果がない」こと、frame-ancestors は「<meta> 要素ではサポートされていない」ことを明記しています。また、frame-ancestors は default-src にフォールバックしない点にも注意してください。default-src 'none' というポリシーでも、誰でもそのページをフレームに埋め込めます。
X-Content-Type-Options
nosniff は、ブラウザーに Content-Type ヘッダーを信頼するよう指示します。これを設定すると、スクリプトやスタイルシートとして要求されたレスポンスは、MIMEタイプが一致しなければブロックされます。画像に偽装してアップロードされたファイルがスクリプトとして実行されるのを防げます。有効な値は1つだけです。
X-Content-Type-Options: nosniff
追加する前に、特に JavaScript と CSS について、サーバーが正しい Content-Type を送信していることを確認してください。
Referrer-Policy
訪問者が他サイトへのリンクをクリックすると、ブラウザーは Referer ヘッダーを送信します。最近のブラウザーは、すでにデフォルトで strict-origin-when-cross-origin を使っています。これはクロスサイトではオリジン(https://example.com/)のみを送り、HTTPSからHTTPへの遷移では何も送りません(MDN)。それでも OWASP は、「ブラウザーのデフォルトに頼るのではなく」明示的に設定することを推奨しています。完全なURL(含まれるトークンも)をどこへでも送信してしまう unsafe-url は避けてください。
Permissions-Policy と、削除すべきヘッダー
Permissions-Policy は、使わないブラウザー機能を無効にし、埋め込みスクリプトがカメラや位置情報を要求できないようにします。MDN は実験的な機能でブラウザーのサポートも限定的としているため、追加の防御層として扱ってください。無料のチェッカーではこのヘッダーを検査しませんが、フルのセキュリティスキャンでは検査します。
追加ではなく削除すべきヘッダーが2つあります。OWASP は、X-XSS-Protection は設定しない(または 0 にする)よう述べています。このヘッダーが制御していた古いフィルターが脆弱性を生む可能性があるためです。また Expect-CT は非推奨としています。さらに X-Powered-By を削除し、Server には情報を含まない値を設定することも推奨しています。
Searvia のセキュリティヘッダーチェッカーの仕組み
無料のセキュリティヘッダーチェッカーは、ウェブサイトSEOチェッカーと同じエンジンで動作し、5つのチェックを優先して表示します。実行するのは訪問者なら誰でも送れる通常のリクエストだけで、攻撃やプローブは一切行いません。
| チェック | 検査方法 | 合格 | 警告 | 不合格 | 優先度 |
|---|---|---|---|---|---|
| HTTPS | HTTPSでページを読み込み、その後リダイレクトを追わずに http:// をリクエスト | HTTPSが機能し、HTTPが https:// のアドレスへリダイレクトされる(HTTPがまったく応答しない場合は注記が表示) | HTTPSが機能しない、またはHTTPがリダイレクトされない | 高 | |
| TLS証明書 | 最終的なホストの証明書を読み取る | 有効でホストと一致し、残り14日以上 | 残り14日未満 | 期限切れ、またはホストをカバーしていない | 高 |
| HSTS | ページのレスポンスから max-age を読み取る | 15,552,000秒(約6か月)以上 | 未設定、またはそれより短い | 低 | |
| Mixed content | HTTPSページ内のスクリプト、iframe、スタイルシート、画像、動画、音声、ソースにある http:// のURLを検出 | なし | 画像またはメディアのみ | スクリプト、iframe、スタイルシート | 中 |
| セキュリティヘッダー | 3つの主要なレスポンスヘッダーを確認し、Referrer-Policy を表示 | 3つすべてあり | いずれかが欠けている | 低 |
カウント対象の3つは、Content-Security-Policy、X-Frame-Options(または frame-ancestors を含むCSPヘッダー)、X-Content-Type-Options です。Referrer-Policy も一覧に表示されますが、未設定でも減点されません。ブラウザーがすでにデフォルトで strict-origin-when-cross-origin を使っており、その旨が表にも記載されるためです。結果の表には各ヘッダーの値が表示され、長いポリシーは短縮されます。
次の制限にご注意ください。
- チェックするのは有無であり、品質ではありません。
'unsafe-inline'だらけのCSPでもここでは合格します。その評価はフルのセキュリティスキャンが行います。 - 読み取るのはHTTPレスポンスヘッダーです。
<meta>タグで設定したCSPもカウントされますが、注記が付きます。frame-ancestorsとレポート機能はそこでは動作しないため、X-Frame-Optionsの代わりにはなりません。Content-Security-Policy-Report-Onlyヘッダーは、強制適用されるポリシーとはみなされません。 - チェックするのは入力した1ページです(ドメインのみ入力した場合はトップページ)。管理画面やAPIなど他のパスでは、異なるヘッダーが送信されている可能性があります。
- mixed content の検出対象はHTMLのみで、タグ内の絶対
http://URLが対象です。CSS や JavaScript が後から要求するファイルは検出されません。
結果の読み方
優先度の高い順に上から対応してください。HTTPSや証明書のチェックの不合格は緊急です。訪問者にブラウザーの警告が表示されたり、通信が暗号化されないまま流れたりします。次に対応すべきはアクティブな mixed content(スクリプト、iframe、スタイルシート)です。ブラウザーがこれらのファイルをブロックし、ページが壊れる可能性があるためです。HSTS とセキュリティヘッダーはスコア上の優先度は低めですが、最も手早く修正できるので、1回の設定変更でまとめて対応しましょう。
チェッカーが報告する各問題の修正方法
「The site does not work over HTTPS.」/「HTTP does not redirect to HTTPS.」
- 証明書をインストールします。Let's Encrypt は無料で、多くのホスティングがワンクリックで対応しています。
- すべての
http://URL から同じhttps://URL への恒久的なリダイレクトを追加します。
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
Cloudflare では、SSL/TLS › Edge Certificates で「Always Use HTTPS」をオンにします。
「The certificate expired N days ago.」/「The certificate does not cover this domain.」
- すぐに更新し、自動更新を有効にします(Certbot や多くのホスティング、CDNではデフォルトで有効です)。
- 証明書に、配信しているすべてのホスト名(最低でもドメイン単体と
www)が含まれていることを確認します。 - 更新が気づかないうちに失敗している場合、よくある原因はDNSレコードの変更、検証用パスのブロック、DNS検証用APIトークンの期限切れです。
残りが14日未満という警告は、たいてい自動更新が機能していないことを意味します。毎回手動で更新するのではなく、原因を調べてください。
「HSTS is not set.」/「HSTS is on but shorter than 6 months.」
HTTPのみのサブドメインを忘れて締め出してしまわないよう、段階的に導入します。
- メインサイトとすべてのサブドメインがHTTPSで動作することを確認します。
Strict-Transport-Security: max-age=300を1日送信し、次に1週間(604800)、その次に1か月と延ばします。max-age=31536000; includeSubDomainsに移行します。- その後で初めて
preloadを検討し、hstspreload.org に申請します。
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
「N files load over plain HTTP.」
- レポートに表示されたURLの一覧を開きます。
- それぞれを
https://に変更するか、自サイトのファイルなら相対パスにします。サードパーティのファイルは、提供元がHTTPSに対応しているか確認し、対応していなければ提供元を替えます。 - データベースとテーマ内にハードコードされた
http://リンクがないか検索します。HTTPSへの移行後は、過去の投稿内容が原因であることが多いです。 - セーフティネットとして
Content-Security-Policy: upgrade-insecure-requestsを追加します。
「N key security headers are missing.」
欠けているヘッダーを1回の変更でまとめて追加します。nginx の場合:
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy-Report-Only "default-src 'self'; frame-ancestors 'self'; report-to csp" always;
Apache の場合:
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Cloudflare では、Transform Rule でレスポンスヘッダーを追加します。Netlify では _headers ファイル、Vercel では vercel.json の headers 設定を使います。nginx では、location ブロック内の add_header がサーバーレベルで設定したヘッダーを置き換えてしまう点に注意してください。ヘッダーを繰り返し記述するか、include ファイルを使います。
CSP については、上のレポートオンリーの行は出発点であり、完成したポリシーではありません。report-to を自分で管理するレポート用エンドポイントに向け、1〜2週間違反を確認してポリシーを調整し、その後ヘッダー名を Content-Security-Policy に変更します。強制適用されると、CSPのチェックは合格になります。
ヘッダーを自分で確認する方法
チェッカーが示すのは、チェックしたページが送信している内容です。他のページ、ファイル、エラーレスポンスでは異なる場合があります。手早く確認する方法は2つあります。
- ブラウザーの DevTools。 Network パネルを開いてページを再読み込みし、最初のリクエストをクリックして Response Headers セクションを読みます。
- コマンドライン。
curl -sI https://www.example.com/でレスポンスヘッダーだけが出力されます。トップページ、下層ページ、PDF、404ページ、ログインページで実行してみてください。
よくある落とし穴は、通常のページには出ているヘッダーがエラーやリダイレクトのレスポンスには出ていないことです。nginx では、always パラメーターを付けない限り、add_header は成功とリダイレクトのレスポンスにしか適用されません。上の例にすべて always が付いているのはそのためです。もう1つは、CDN やホスティングがヘッダーを追加または削除するケースです。サーバーの設定ファイルだけでなく、外部に公開されているレスポンスを確認してください。
各ヘッダーが守る対象はそれぞれ異なります。完璧な CSP も期限切れの証明書には何の役にも立たず、HSTS も挿入されたスクリプトには無力です。目標は、適切な順序で追加した一式をそろえることです。
具体例(架空)
以下は架空の例であり、実際のデータではありません。架空の法律事務所 Halden Legal は、法人クライアントからウェブサイトのヘッダーについてセキュリティ質問票を受け取りました。セキュリティヘッダーチェッカーの結果は次のとおりです。
- HTTPS、TLS証明書:合格、残り61日。
- HSTS:警告、
max-age=86400(1日)。 - Mixed content:警告、2枚の画像がHTTPで読み込まれている(パートナーのバッジと古いチーム写真)。
- セキュリティヘッダー:主要ヘッダー2つが欠落。設定されているのは
X-Content-Type-Optionsのみで、Referrer-Policyにはブラウザーのデフォルトが表示される。
修正は午後1回で終わります。2つの画像URLをHTTPSに変更します。クライアントポータルのサブドメインがHTTPSで動作することを確認したうえで、HSTS を1週間かけて2段階で max-age=31536000; includeSubDomains に引き上げます。サーバーに X-Frame-Options: SAMEORIGIN と Referrer-Policy: strict-origin-when-cross-origin を追加します。レポートオンリーの CSP を10日間運用したところ、予約ウィジェットのインラインスクリプトが見つかりました。これをファイルに移して配信元で許可したうえで、ポリシーを強制適用します。最終実行ではすべてのチェックに合格し、事務所は共有レポートへのリンクを添えて質問票に回答しました。
1時間でできるチェックリスト
- セキュリティヘッダーチェッカーを実行し、まずHTTPSと証明書の不合格を修正する。
- レポートに記載された mixed content を取り除く。
X-Content-Type-Options、Referrer-Policy、そしてX-Frame-Optionsまたはframe-ancestorsを追加する。- すべてのサブドメインがHTTPSで動作したら、HSTS を段階的に1年まで引き上げる。
- レポートオンリーの CSP を開始し、レビューの予定を入れる。
X-Powered-By、Server内のバージョン番号、0以外のX-XSS-Protectionを削除する。
Searvia がサイトのセキュリティを継続的に見守る方法
無料のセキュリティヘッダーチェッカーは、トップページまたは入力した任意のページを、登録不要で約20秒でチェックします。同じレポートには、検索での表示、クロール、速度、モバイル、メール認証に関する33のチェックも含まれます。
無料の Searvia アカウントでは、毎週のセキュリティスキャンが追加されます。暗号化、ブラウザー保護、Cookie フラグ、ソフトウェアのバージョン、メールのなりすまし対策を受動的にチェックし、各発見事項を裏付けるリクエストとレスポンスを提示します。CSP の評価(たとえば nonce やハッシュのない 'unsafe-inline')や Permissions-Policy の確認も行い、所有権を確認すれば、公開されている .env や .git ファイル、公開バックアップ、デバッグページ、安全でない CORS も調べます。Write the remediation plan with AI は、発見事項をそのまま貼り付けられる設定に変換します(5クレジット)。Starter 以上の有料プランでは、死活監視が TLS 証明書も毎日チェックし、期限が切れる前に通知します。
よくあるご質問
- セキュリティヘッダーとは何ですか?
- セキュリティヘッダーは、ページをより安全に扱うようブラウザーに伝えるHTTPレスポンスヘッダーです。常にHTTPSを使う(Strict-Transport-Security)、許可された配信元のスクリプトだけを実行する(Content-Security-Policy)、他サイトによるフレーム埋め込みを許可しない(X-Frame-Options または frame-ancestors)、ファイルタイプを推測しない(X-Content-Type-Options)、Referer ヘッダーで送信される情報を制限する(Referrer-Policy)といった指示を出します。設定はページの内容ではなく、サーバーまたはCDNで行います。
- セキュリティヘッダーはSEOに影響しますか?
- 個別のランキング要因としては影響しません。Google のページエクスペリエンスに関するガイダンスは、ページが安全に配信されているかを問うため、HTTPSは重要です。HTTPSの不具合や mixed content は、訪問者と信頼を損ないます。Content-Security-Policy や X-Frame-Options などのヘッダーは攻撃からユーザーを守るもので、その価値はセキュリティにあり、順位ではありません。
- HSTS の max-age はどのくらいが適切ですか?
- 1年(max-age=31536000)が一般的で、HSTS プリロードリストの最低条件でもあります。プリロードには includeSubDomains と preload も必要です。ブラウザーはその期間中、通常のHTTPを拒否するため、すべてのサブドメインがHTTPSで動作することを確認しながら、数分、1週間、1か月と低い値から段階的に始めてください。当チェッカーは約6か月以上の値を合格とします。
- X-Frame-Options と frame-ancestors のどちらを使うべきですか?
- どちらでも問題ありません。Content-Security-Policy の frame-ancestors はより柔軟な現代的な方法で、X-Frame-Options は古い代替手段です。ページを他の場所に埋め込む必要がまったくない場合は、frame-ancestors 'self' または X-Frame-Options: SAMEORIGIN を使います。どちらも meta タグでは機能せず、HTTPヘッダーとして送信する必要があります。
- X-XSS-Protection はまだ必要ですか?
- いいえ。OWASP は、設定しないか、X-XSS-Protection: 0 で明示的に無効にすることを推奨しています。このヘッダーが制御していた古いブラウザーのXSSフィルターが、脆弱性を生む可能性があったためです。代わりに、インラインスクリプトをブロックする Content-Security-Policy を使ってください。
ソース
- HTTP Security Response Headers Cheat Sheet – OWASP
- Strict-Transport-Security – MDN Web Docs
- HSTS Preload List Submission – hstspreload.org
- Content Security Policy (CSP) – MDN Web Docs
- CSP: frame-ancestors – MDN Web Docs
- X-Frame-Options – MDN Web Docs
- X-Content-Type-Options – MDN Web Docs
- Referrer-Policy – MDN Web Docs
- Permissions-Policy – MDN Web Docs
- Mixed content – MDN Web Docs
- Understanding page experience in Google Search results – Google Search Central
- Module ngx_http_headers_module – nginx documentation
- A secure web is here to stay – Chromium Blog