セキュリティ ヘッダーとは HSTS・ CSPなど 6つの 意味と、 壊さない 設定の順番
- 6つは、HSTS、CSP、nosniff、埋め込み、参照元、機能の制限です。
- 壊れにくい順に、1つずつ入れて確かめます。
- HSTSは短い期間から、CSPは報告だけから始めます。

セキュリティヘッダーは、Webサイトが返す応答に付ける、ブラウザへの指示です。 HSTSは「次からはhttpsだけで来て」、CSPは「読み込んでよいものの出どころはここだけ」、というように、ブラウザの動きを絞ります。ここでは、当サイトの無料ツールが確かめる6つ(Strict-Transport-Security、Content-Security-Policy、X-Content-Type-Options、X-Frame-Options、Referrer-Policy、Permissions-Policy)を扱います。
設定を間違えると、サイトが開けなくなったり、スクリプトが動かなくなったりします。特に、HSTSのpreloadと、CSPには注意が必要です。この記事では、6つの意味、安全に始められる値、間違えたときに起きること、入れていく順番、Apache、nginx、Cloudflareでの設定の仕方を、公式の資料にもとづいて整理します。
内容は、2026年10月23日に、MDN Web DocsのStrict-Transport-Security、Content Security Policy、X-Content-Type-Options、X-Frame-Options、Referrer-Policy、Permissions-Policy、HSTS preloadの公式サイト、Apacheのmod_headers、nginxのngx_http_headers_module、CloudflareのResponse Header Transform Rules、Managed Transforms、HSTSの説明と照らし合わせました。
自分のサイトにどのヘッダーがあるかは、サイトのPHPとヘッダーを確かめる無料ツールで、通常のGETを1回送るだけで見られます。
6つの ヘッダーの一覧
| ヘッダー | 何を | 始めやすい値 | 間 |
|---|---|---|---|
| ヘッダーStrict-Transport-Security(HSTS) | 何をするか次からは | 始めやすい値短い | 間違えるとhttpsが |
| ヘッダーContent-Security-Policy(CSP) | 何をするか読み込んで | 始めやすい値まず | 間違えるとスクリプトや |
| ヘッダーX-Content-Type-Options | 何をするかファイルの | 始めやすい値nosniff | 間違えると種類を |
| ヘッダーX-Frame-Options | 何をするかほかの | 始めやすい値DENY、 | 間違えると自社の |
| ヘッダーReferrer-Policy | 何をするかリンク先へ | 始めやすい値strict-origin-when-cross-origin | 間違えると提携先が、 |
| ヘッダーPermissions-Policy | 何をするかカメラや | 始めやすい値使わない | 間違えると自社の |
「始めやすい値」は、MDNの例と説明にもとづく、当サイトの提案です。サイトによって、適した値は変わります。
01 HSTS(Strict-Transport-Security)
MDNによると、max-ageは、ブラウザが「このサイトはhttpsだけで開く」と覚えておく秒数です。includeSubDomainsを付けると、サブドメインにも適用されます。MDNの例は、次の2つです。
Strict-Transport-Security: max-age=31536000; includeSubDomainsStrict-Transport-Security: max-age=63072000; includeSubDomains; preloadMDNは、始めの値を勧めてはいません。1年(31536000秒)は、preloadに必要な最小の値としています。
壊れるとき
- httpsが使えなくなると、サイトが開けなくなります。 Cloudflareの説明では、httpsをやめると、
max-ageの間、または再びhttpsを有効にするまで、訪問者はサイトを開けなくなります - サブドメインも対象です。
includeSubDomainsを付けると、httpsに対応していないサブドメインは開けなくなります - preloadは、簡単には戻せません。 hstspreload.orgは、一覧への登録は簡単には取り消せず、Chromeの更新で変更が利用者に届くまでに数か月かかるとしています。サイト全体とすべてのサブドメインを、長期にわたってhttpsで出せると確信できるときだけ申し込むよう書かれています。また、preloadを既定で付けないよう求めています
- httpでは効きません。 MDNによると、HSTSをやめる場合は
max-age=0にしますが、これは、ブラウザがhttpsで接続して、応答を受け取ったときにだけ効きます
当サイトの 勧め方
短い期間から始めて、問題がなければ延ばします(当サイトの提案で、MDNの推奨ではありません)。たとえば、数分、1週間、1か月、1年の順です。includeSubDomainsは、すべてのサブドメインがhttpsで動くことを確かめてから付けます。preloadは、最後に、必要なときだけです。
02 CSP(Content-Security-Policy)
CSPは、読み込んでよいスクリプト、画像、スタイルの出どころを、ブラウザに伝える設定です。MDNの例は、次のとおりです。
Content-Security-Policy: default-src 'self'; img-src 'self' example.comdefault-src 'self'は、同じ出どころからだけ読み込む、という意味です。img-srcで、画像にだけ別の出どころを足しています。
壊れるとき
MDNによると、CSPにdefault-srcかscript-srcがあると、そのままではインラインのJavaScriptは動きません。<script>の中のコード、onclickのような属性、javascript:のURLが対象です。eval()なども止まります。Googleアナリティクスのタグや、チャットのウィジェットなど、外から読み込むものや、ページに直接書いたスクリプトを使っているサイトは、設定を間違えると、動かなくなります。
'unsafe-inline'で止まらないようにできますが、MDNは、CSPの目的の多くを失うので避けるよう書いています。同じ指定にnonceかハッシュがあると、'unsafe-inline'はブラウザに無視されます。代わりに、ランダムな値(nonce)か、ハッシュを使う方法があります。nonceは、応答ごとに変わる値が必要なので、静的なHTMLでは使えません。
まず、 報告だけの モードから
MDNは、CSPを報告だけのモードで出せると説明しています。このモードでは、ポリシーは強制されず、違反だけが報告先に送られます。
Content-Security-Policy-Report-Only: default-src 'self'; report-to csp-endpoint
Reporting-Endpoints: csp-endpoint="https://example.com/csp-reports"MDNに、段階ごとの手順は書かれていません。MDNの説明から導ける進め方は、次のとおりです(当サイトの整理です)。
- 報告だけのモードで出す
- 報告された違反を見て、正当なものは許可し、インラインのスクリプトはnonceかハッシュに変える
- 違反が出なくなったら、強制するヘッダーに切り替える
報告だけのモードは、<meta>では使えません。また、報告を受ける場所は、自分で用意する必要があります。
03 X-Content-Type-Options
値はnosniffだけです。MDNによると、スクリプトやスタイルの要求では、返された種類(MIME type)が、JavaScriptやtext/cssでなければ、ブラウザはその応答を止めます。それ以外では、ブラウザは中身から種類を推測せず、示された種類をそのまま使います。
壊れるのは、スクリプトやスタイルを、正しくない種類で返しているサイトです。入れる前に、スクリプトとスタイルが正しい種類で返っているかを確かめます。
04 X-Frame-Options と frame-ancestors
MDNの説明では、DENYは、どこの枠にも埋め込めません。SAMEORIGINは、同じ出どころのページからだけ埋め込めます。ALLOW-FROMは廃止されていて、モダンなブラウザは無視します。
より細かく決めたいときは、CSPのframe-ancestorsを使います。MDNは、埋め込まれる必要がなければ、frame-ancestors 'none'にするよう書いています。
Content-Security-Policy: frame-ancestors 'none'当サイトのツールは、X-Frame-Optionsという名前のヘッダーがあるかを見ます。frame-ancestorsだけを設定しているサイトでは、X-Frame-Optionsが「要確認」と出ることがあります。その場合は、CSPの中身を自分で確かめてください。
05 Referrer-Policy
リンクを開いたときに、元のページのURLのどこまでを、リンク先に伝えるかを決めます。MDNによると、何も設定しないか、値が正しくない場合、最近のブラウザはstrict-origin-when-cross-originを使います。つまり、設定がなくても、何も送られないわけではありません。
strict-origin-when-cross-originでは、同じサイトの中では完全なURLが、ほかのサイトにはサイト名だけ(https同士の場合)が送られ、httpsからhttpへは何も送られません。MDNは、unsafe-urlは、非公開の情報を含むURLを漏らすおそれがあるとして、注意を求めています。
Referrer-Policy: strict-origin-when-cross-origin06 Permissions-Policy
カメラ、マイク、位置情報などの機能を、どのページで使えるようにするかを決めます。MDNの例は、次のとおりです。()は、その機能をすべて使えなくする、という意味です。
Permissions-Policy: camera=(), microphone=(), geolocation=()MDNは、このヘッダーを実験的で、一部のブラウザでは使えないと説明しています。本番で頼る前に、対応状況を確かめてください。また、<iframe>で外のサービス(地図や動画など)を埋め込んでいるサイトは、その機能まで止めないよう注意します。
入れていく順番
6つを一度に入れると、どれが原因で壊れたのか分からなくなります。壊れにくい順に、1つずつ入れます。この順番は、MDNなどの説明から整理した、当サイトの提案です。
| 順 | ヘッダー | 理由 |
|---|---|---|
| 順1 | ヘッダーReferrer-Policy | 理由ブラウザの |
| 順2 | ヘッダーX-Content-Type-Options | 理由種類を |
| 順3 | ヘッダーX-Frame-Options、 | 理由埋め込みを |
| 順4 | ヘッダーPermissions-Policy | 理由使っていない |
| 順5 | ヘッダーHSTS | 理由短い |
| 順6 | ヘッダーCSP | 理由最も |
1つ入れるたびに、トップページ、ログイン、問い合わせフォーム、決済など、大事なページを、ブラウザで開いて確かめます。
主な ホスティングでの設定
Apache (.htaccess を含む)
mod_headersのHeaderディレクティブを使います。mod_headersの説明では、このディレクティブは.htaccessでも使え、上書きの種類はFileInfoとされています。つまり、サーバーの設定でAllowOverrideがそれを許していないと、.htaccessでは効きません。alwaysを付けると、エラーの応答にも付きます。
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"mod_headersが有効でないと動きません。レンタルサーバーでは、.htaccessの書き方の制限がある場合があります。サーバー会社の説明を見てください。
nginx
ngx_http_headers_moduleのadd_headerを使います。注意点が2つあります。
- 既定では、
add_headerは、応答のコードが200、201、204、206、301、302、303、304、307、308のときだけ付きます。エラーの応答にも付けたいときは、alwaysを付けます - 上の階層(
httpやserver)のadd_headerは、今の階層にadd_headerが1つもないときだけ引き継がれます。locationの中にadd_headerを1つ書くと、上の階層のものが消えます
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;Cloudflare
3つの方法があります。
- Response Header Transform Rule ダッシュボードのRulesから「Create rule」、「Response Header Transform Rule」を選び、「Modify response header」で「Set static」にして、ヘッダーの名前と値を入れます。Cloudflareの説明では、同じ名前のヘッダーがあれば上書きされます。ダッシュボードの手順によると、1つのルールで30個まで設定できます
- HSTS 「Edge Certificates」のページに、HSTSの設定があります。期間は1か月から12か月で選びます。httpsに対応してから有効にするよう、Cloudflareは警告しています
- Managed Transforms の「Add security headers」 Cloudflareの説明では、X-Content-Type-Options(nosniff)、X-XSS-Protection、X-Frame-Options(SAMEORIGIN)、Referrer-Policy(same-origin)、Expect-CTを付けます。上の「始めやすい値」と違う値があり、Cloudflareも、サイトに影響する可能性があると書いています。使うなら、値を確かめてからにします
設定した あとに 確かめる
- ブラウザの開発者ツールのネットワークの画面で、応答のヘッダーを見ます
- 無料ツールで、6つのヘッダーが「設定あり」になったかを見ます。このツールは、ヘッダーがあるかどうかを見るもので、値が適切かまでは判断しません。CSPの中身が強いか弱いか、HSTSの期間が十分かは、自分で確かめてください
- 大事なページを、実際に開いて、動くことを確かめます
よく ある質問
HSTSとは 何ですか?
次からはhttpsだけでアクセスするよう、ブラウザに覚えさせる設定です。httpsが使えなくなると、期間の間、サイトが開けなくなります。短い期間から始めて、延ばします。
HSTSの preloadは 付けた ほうが よいですか?
必要なときだけです。hstspreload.orgは、一覧への登録は簡単には取り消せず、Chromeでは変更が届くまで数か月かかるとしています。サイト全体とすべてのサブドメインを長期にわたってhttpsで出せると確信できるときだけ申し込みます。
CSPを 入れたら サイトが 動かなくなりました。 どうすれば よいですか?
まず、強制するヘッダーを外します。そのうえで、報告だけのモード(Content-Security-Policy-Report-Only)で出して、報告された違反を見ながら、許可する出どころを足します。インラインのスクリプトは、nonceかハッシュに変えます。
セキュリティヘッダーは、 全部 入れないと いけませんか?
必ずではありません。影響の小さいものから、1つずつ入れます。使っていない機能を止めるPermissions-Policyや、nosniffは、比較的入れやすいものです。CSPは、最後に報告だけのモードから始めます。
レンタルサーバーでも 設定できますか?
Apacheなら、.htaccessで設定できる場合があります。ただし、サーバー会社によって、書き方の制限があります。サーバー会社の説明を見てください。Cloudflareを使っているなら、ダッシュボードから設定できます。


