セキュリティマガジン盾 - TATE -

Content Security Policy(CSP)をApacheで設定する方法:ヘッダの書き方とよくあるエラー

タグ:cspapachexss
最終更新日 2026年01月12日 投稿日 2026年01月12日
CSPをApacheで設定する画像

本記事では、様々な企業がよく使用するWebサーバーのApacheでCSPヘッダを正しく設定するための前提知識(設定場所の選び方、mod_headers、Header set/always setの違い、HTTPS環境での注意)を整理します。

まずはdefault-src 'self'から始めるコピペ例、CDNやGoogle Fonts、data:画像の許可、object-src 'none'frame-ancestorsまで実用例を紹介します。さらに「効かない」「画面が崩れる」原因になりやすいインラインScriptやイベント、許可漏れ、オリジン違い、書き方ミスの直し方も解説します。

目次

そもそもContent Security Policy(CSP)とは?

Content Security Policy(CSP)は、ブラウザに「読み込んでよいスクリプトや画像の範囲」を指示してXSSなどを抑える仕組みです。

詳しくは別の記事で解説していますので、参考にしてみてください。

参考記事:CSP(Content Security Policy)とは?XSS対策に欠かせない理由と注意点

ApacheでCSPヘッダを設定する前に知ること(前提と注意点)

ApacheでCSPヘッダを設定する場合は、Apache特有の設定方法や注意点があるので覚えていきましょう。

設定場所の選び方:httpd.conf / VirtualHost / Directory / .htaccess

CSPの設定方法は「どのファイル・ブロックでヘッダを付けるか」で挙動が変わります。

  • httpd.conf:Apache全体に適用したいときに使う設定ファイル。CSPヘッダの書き方をここに置くと、原則すべてのサイト/パスに効く。全体方針を決めたい場合向き。
  • VirtualHost:ドメイン・ポート(例::80 / *:443)単位で設定を分けたいときに使う。HTTPSサイトだけCSPを強める、特定サイトだけ外部CDNやdata:を許可する、といった設定方法に向く。
  • Directory:特定ディレクトリ配下にだけ適用したいときに使う。管理画面だけ厳しいCSP、公開側だけ緩める、などパス単位で調整できる。
  • .htaccess:サーバ設定ファイルを触れない環境(レンタルサーバ等)で、ディレクトリごとに手軽に設定したいときに使う。ただしAllowOverrideの設定次第で無効だったり、上位(httpd.conf/VirtualHost)に上書きされて「ヘッダが効かない」原因になりやすい。

目的に応じて、適切なファイル・ブロックにCSPを設定するように意識しましょう

mod_headers(Headerディレクティブ)が必要

CSPとはレスポンスヘッダでブラウザに制約を伝える仕組みなので、Apache側でそのヘッダを付ける機能が必要です。そこで使うのがmod_headersで、これが有効でないとHeader set Content-Security-Policy ...のような書き方をしてもCSPが返りません。

# 例:httpd.conf(または conf.modules.d/*.conf)で mod_headers を有効化 LoadModule headers_module modules/mod_headers.so

上記の様にmod_headersLoadModule で読み込んで有効化することができます。

modules/mod_headers.so のパスは環境で違うので、既存の LoadModule 行の書き方に合わせてください。設定後は Apache を再読み込み/再起動します。

Header set と Header always set の違い(効かない原因になりがち)

ApacheでCSPヘッダを付ける設定方法では、Header setHeader always setの違いが「効かない」原因になりがちです。

  • Header set通常のレスポンスに指定したヘッダを付ける書き方。状況によっては(リダイレクトやエラー応答など)ヘッダが付かず、CSPが「効いていない」と見える原因になりやすい。
  • Header always set:通常のレスポンスに加えて、リダイレクトやエラー応答などでもヘッダを付けやすい書き方。CSPのように「常に返して効かせたい」ヘッダは基本こちらが無難。

HTTPS/SSL環境での設定位置(VirtualHost *:443 の考え方)

HTTPS/SSL環境では、CSPヘッダの設定位置を間違えると「HTTPでは付くのにHTTPSでは付かない」状態になりがちです。

Apacheでは443番ポート用に<VirtualHost *:443>が別に定義されていることが多く、CSPの書き方はその中に書くのが基本です。逆に*:80側だけに設定すると、実際に閲覧されるHTTPS応答には反映されません。

いきなり本番適用しない:まずReport-Onlyで安全に試す

CSPはいきなり本番適用すると、必要な外部JSやCSSまでブロックして画面崩れや機能停止を起こすことがあります

# httpd.conf / VirtualHost / Directory など Header always set Content-Security-Policy-Report-Only "default-src 'self'"

そこで最初は上記の様にReport-Onlyを使い、実際にはブロックせず「違反ログだけ出す」設定方法で影響範囲を確認します。Content-Security-Policy-Report-Onlyヘッダとして通常と同じ書き方で付与でき、default-src 'self'から始めて段階的に影響範囲を調整していくといいです。

Apacheでの設定方法:コピペで使えるCSP設定例(基本〜実用)

ApacheにおけるCSPの設定例について、ここではシチュエーションごとにまとめます。参考にしてみてください。

例:default-src 'self'(まずはこれ)をApacheで返す

最小構成。基本は同一オリジン以外を遮断。

Header always set Content-Security-Policy "default-src 'self'"

例:script-srcで外部JSを許可(Google Analytics / CDNなど)

自サイト+特定ドメインだけJSを許可。必要な外部だけ追加する。

Header always set Content-Security-Policy "default-src 'self'; script-src 'self' https://www.googletagmanager.com https://www.google-analytics.com"

例:style-srcで外部CSSやフォントを許可(Google Fontsなど)

外部CSS(fonts.googleapis.com)とフォント本体(fonts.gstatic.com)を許可。

Header always set Content-Security-Policy "default-src 'self'; style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com"

例:img-srcでdata:を許可(data URI画像が表示されない対策)

SVGアイコン等で data: を使うサイト向け。

Header always set Content-Security-Policy "default-src 'self'; img-src 'self' data:"

例:object-src 'none' でプラグイン系を遮断(安全側の基本)

Flash等のプラグイン埋め込みを無効化。基本“none推奨”。

Header always set Content-Security-Policy "default-src 'self'; object-src 'none'"

例:frame-ancestors で埋め込み制御(クリックジャッキング対策にも)

他サイトから iframe 埋め込みされるのを防ぐ(または許可先を限定)。

# 埋め込み全面禁止 Header always set Content-Security-Policy "default-src 'self'; frame-ancestors 'none'"

よくあるエラー集:表示崩れ・機能停止を最短で直すコツ

ここではApacheでCSPを設定する際によく起きるエラーの解決方法についてまとめましたので、参考にしてみてください。

エラー:そもそもヘッダが付かない(mod_headersが無効)

  • 症状:Content-Security-Policy がレスポンスに出ない
  • 原因:mod_headers が読み込まれていない
  • 確認:apachectl -M | grep headers(headers_module が出るか)
  • 対処(例)
LoadModule headers_module modules/mod_headers.so

エラー:.htaccessに書いたのに無視される(AllowOverride)

  • 症状:.htaccess に書いたのにヘッダが付かない
  • 原因:AllowOverride None などで .htaccess が無効、または FileInfo が許可されてない
  • 対処(例)
<Directory "/var/www/html"> AllowOverride FileInfo </Directory>

エラー:設定場所が違う(VirtualHostに書いたつもりが別サイトに効いてる)

  • 症状:Aサイトに入れたはずがBサイトに付く/付かない
  • 原因:CSP設定が別の <VirtualHost> に入っている、または想定と違う vhost がマッチしている
  • 対処:該当ドメインの <VirtualHost> ブロック内に書く(ServerName/ServerAliasも確認)

エラー:HTTPでは付くのにHTTPSでは付かない(*:443側に書いてない)

  • 症状:http:// だとヘッダが出るが https:// だと出ない
  • 原因::80 の vhost にしか書いていない(SSL用は別の<VirtualHost *:443>
  • 対処(例)
<VirtualHost *:443> Header always set Content-Security-Policy "default-src 'self'" </VirtualHost>

エラー:Header set だと一部応答で付かない(alwaysを使うべき)

  • 症状:通常ページは付くが、リダイレクト/エラー応答で付かないことがある
  • 原因:Header set の挙動差
  • 対処:基本は Header always set を使う
Header always set Content-Security-Policy "default-src 'self'"

エラー:同じヘッダが二重に付く(どこかで重複設定)

  • 症状:レスポンスに Content-Security-Policy が2行以上出る
  • 原因:httpd.conf と vhost、vhost と .htaccess などで二重設定
  • 対処:設定箇所を統一するか、意図して上書きする
Header unset Content-Security-Policy Header always set Content-Security-Policy "default-src 'self'"

エラー:反映されない(再起動/リロード忘れ or 読んでるファイルが違う)

  • 症状:設定を変えたのにヘッダが変わらない
  • 原因:Apache再読み込みしてない/別の設定ファイルを編集している
  • 対処apachectl -t -D DUMP_INCLUDES で読み込み元を確認、systemctl reload httpd等で反映

エラー:書式エラーでApacheが起動しない(引用符・セミコロン・クォート崩れ)

  • 症状:起動時に設定エラー、またはCSPが途中で途切れる
  • 原因:ダブルクォート " の閉じ忘れ、全角記号、改行混入など
  • 対処apachectl configtest で検知して直す

エラー:304/キャッシュで「変わってないように見える」

  • 症状:DevToolsで確認するとヘッダが見えたり見えなかったり
  • 原因:304 Not Modified の扱い、表示方法の勘違い
  • 対処:DevToolsのNetworkで該当リクエストを選び、Response Headers を見る/curl -I で確認

エラー:リバースプロキシ/上流がヘッダを消している

  • 症状:Apacheで付けてるはずなのに、外から見ると無い
  • 原因:手前のCDN/プロキシや別Apache(フロント)がヘッダを上書き/削除
  • 対処:実際にインターネットから見える最終レスポンスで curl -I https://... を確認し、どの層で消えてるか切り分け

まとめ

ここまでApacheでCSPを設定するやり方やエラーパターンなどについて解説しました。まとめると下記の通りです。

  • CSPは、ブラウザに読み込みルールを指示してXSS等を抑えるセキュリティヘッダ
  • Apacheでは「どこに書くか」(httpd.conf / VirtualHost / Directory / .htaccess)で効き方が変わる
  • CSPヘッダ付与には mod_headers が必須で、LoadModule headers_module ... で有効化する
  • Header set は一部応答で付かない場合があるため、基本は Header always set を使う
  • HTTPS環境では <VirtualHost *:443> 側にも設定しないと「HTTPSだけ効かない」になりやすい
  • いきなり本番適用せず、まずは Content-Security-Policy-Report-Only で影響を確認してから切り替える
  • 設定は default-src 'self' から始め、必要に応じて外部JS/CDN、Google Fonts、data: 画像などを段階的に許可する
  • よくある「効かない」原因は、mod_headers未有効、.htaccess無効(AllowOverride)、設定箇所違い、HTTPS側未設定、ヘッダ重複、反映忘れ、書式ミス、キャッシュ/304、上流でのヘッダ削除

ApacheでCSPの設定をする際は是非参考にしてみてください。まずはReport-Onlyから入れて、DevTools等でヘッダを確認してみましょう。