2026年5月20日
2026年5月20日
WordPressのContent Security Policy(CSP)エラーを解決する方法
はじめに
ブラウザコンソールに「Refused to load the script because it violates the following Content Security Policy directive」と表示されてJavaScriptが動かない、プラグインのスタイルがブロックされてデザインが崩れる、Google FontsやYouTubeの埋め込みが表示されない。CSPは強力なセキュリティ機能ですが、設定が厳しすぎると正常なコンテンツもブロックされます。
症状・原因
CSPエラーが発生する主な原因:
default-src 'self'のみ設定:外部リソースを全てブロックしているunsafe-inlineの欠如:WordPressのインラインスクリプト・スタイルがブロックされる- 外部ドメインの未許可:Google Fonts・YouTube・Gravatar等が許可されていない
- フレーミング制限:
frame-ancestors設定でiframeが使えない
解決手順
ステップ1:CSPエラーの内容を確認する
// ブラウザコンソールのエラー例
Refused to load the script 'https://www.googletagmanager.com/gtag/js'
because it violates the following Content Security Policy directive:
"script-src 'self'"
// → script-src に googletagmanager.com を追加する必要がある
ステップ2:WordPress向けの基本CSP設定
// functions.php — WordPressに適したCSPヘッダーを設定
add_action('send_headers', function() {
$csp = implode('; ', [
"default-src 'self'",
// スクリプト:WordPress + 一般的な外部サービス
"script-src 'self' 'unsafe-inline' 'unsafe-eval' " .
"https://www.google-analytics.com " .
"https://www.googletagmanager.com " .
"https://connect.facebook.net",
// スタイル:インラインスタイルとGoogle Fonts
"style-src 'self' 'unsafe-inline' " .
"https://fonts.googleapis.com",
// フォント
"font-src 'self' " .
"https://fonts.gstatic.com " .
"data:",
// 画像:データURIとGravatar
"img-src 'self' data: " .
"https://*.gravatar.com " .
"https://secure.gravatar.com " .
"https://www.google-analytics.com",
// フレーム:YouTube・Vimeo
"frame-src 'self' " .
"https://www.youtube.com " .
"https://player.vimeo.com",
// 接続先
"connect-src 'self' " .
"https://www.google-analytics.com",
// XSS対策のアップグレード
"upgrade-insecure-requests",
]);
header("Content-Security-Policy: $csp");
});
ステップ3:nonceベースのCSPでinline-scriptを安全に許可する
'unsafe-inline'を使わずインラインスクリプトを許可するより安全な方法:
// functions.php — nonceベースのCSP
add_action('init', function() {
// wp_headでnonceを生成
$nonce = base64_encode(random_bytes(16));
// スクリプトタグにnonce属性を追加するフィルター
add_filter('script_loader_tag', function($tag, $handle) use ($nonce) {
return str_replace('<script ', '<script nonce="' . $nonce . '" ', $tag);
}, 10, 2);
// CSPヘッダーにnonceを含める
add_action('send_headers', function() use ($nonce) {
header("Content-Security-Policy: script-src 'self' 'nonce-$nonce'");
});
});
ステップ4:Report-Only モードでテストする
本番環境で直接CSPを有効化する前に、レポートモードでテストします。
// functions.php — レポートモード(ブロックせずエラーをログ)
add_action('send_headers', function() {
header("Content-Security-Policy-Report-Only: " .
"default-src 'self'; " .
"report-uri /csp-report-endpoint"
);
});
// レポートを受信するエンドポイント
add_action('rest_api_init', function() {
register_rest_route('csp/v1', '/report', [
'methods' => 'POST',
'callback' => function($request) {
$report = $request->get_json_params();
error_log('CSP Report: ' . json_encode($report));
return new WP_REST_Response(null, 204);
},
'permission_callback' => '__return_true',
]);
});
ステップ5:.htaccessでCSPを設定する
<IfModule mod_headers.c>
Header always set Content-Security-Policy "\
default-src 'self'; \
script-src 'self' 'unsafe-inline' https://www.googletagmanager.com; \
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; \
font-src 'self' https://fonts.gstatic.com; \
img-src 'self' data: https:; \
frame-src https://www.youtube.com; \
upgrade-insecure-requests"
</IfModule>
注意事項
'unsafe-inline'と'unsafe-eval'を許可するとCSPの効果が弱まりますが、WordPressの多くのプラグインはこれらを必要とします。- CSPはセキュリティと利便性のトレードオフです。まず
Report-Onlyモードでテストしてから本番に適用してください。
まとめ
CSPエラーはコンソールのエラーメッセージから許可が必要なドメインを特定し、対応するディレクティブ(script-src・style-src・font-src等)に追加することで解決します。まずContent-Security-Policy-Report-Onlyでテストし、問題がないことを確認してから本番環境に適用しましょう。関連記事:Mixed Contentエラーの解決方法、CORSエラーの解決方法