DevToolBox無料
ブログ

Content Security Policy (CSP) 完全ガイド:基礎から本番まで

12分by DevToolBox

CSPはXSS攻撃に対する最も効果的な防御手段の一つです。ブラウザにどのリソースの読み込みを許可するかを指示することで、脆弱性があっても悪意のあるコード注入を防ぎます。

CSPとは?なぜ重要?

CSPはHTTPレスポンスヘッダーで、ブラウザが読み込み可能なリソースを制御します。

CSPの仕組み

ブラウザがCSPヘッダーを受信すると、ルールに違反するリソースをブロックします:

Browser receives HTTP response:
  Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com

Browser allows:
  ✅ <script src="/app.js">              (same origin = 'self')
  ✅ <script src="https://cdn.example.com/lib.js">

Browser blocks:
  ❌ <script src="https://evil.com/steal.js">
  ❌ <script>alert('XSS')</script>       (inline = not allowed)

CSPディレクティブ一覧

ディレクティブ制御対象
default-srcFallback for all resource types'self'
script-srcJavaScript files and inline scripts'self' https://cdn.example.com
style-srcCSS stylesheets and inline styles'self' 'unsafe-inline'
img-srcImages (img, favicon, CSS background)'self' data: https:
font-srcWeb fonts (@font-face)'self' https://fonts.gstatic.com
connect-srcXHR, fetch, WebSocket, EventSource'self' https://api.example.com
media-srcAudio and video elements'self'
frame-srcIframes and embedded frames'self' https://www.youtube.com
object-srcPlugins (Flash, Java applets)'none'
base-uriBase element URLs'self'
form-actionForm submission targets'self'
frame-ancestorsWho can embed this page (anti-clickjacking)'self'
upgrade-insecure-requestsUpgrade HTTP requests to HTTPS(no value needed)

ソース値の説明

ソース意味
'self'Same origin (protocol + host + port)
'none'Block all resources of this type
'unsafe-inline'Allow inline scripts/styles (reduces security!)
'unsafe-eval'Allow eval(), Function(), setTimeout(string)
'strict-dynamic'Trust scripts loaded by already-trusted scripts
'nonce-abc123'Allow specific inline script with matching nonce attribute
'sha256-...'Allow inline script matching this hash
https:Allow any HTTPS resource
data:Allow data: URIs (e.g., inline images)
blob:Allow blob: URIs
*.example.comAllow all subdomains of example.com

段階的な実装

ステップ1: レポートオンリーモードで開始

サイトを壊さずに違反を特定:

Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report

ステップ3: ポリシーを構築

結果に基づいてポリシーを作成:

Content-Security-Policy:
  default-src 'self';
  script-src 'self' https://cdn.example.com;
  style-src 'self' 'unsafe-inline';
  img-src 'self' data: https:;
  font-src 'self' https://fonts.gstatic.com;
  connect-src 'self' https://api.example.com;
  frame-ancestors 'self';
  base-uri 'self';
  form-action 'self';
  object-src 'none';
  upgrade-insecure-requests

一般的なCSP設定

厳格なポリシー

Content-Security-Policy:
  default-src 'none';
  script-src 'self';
  style-src 'self';
  img-src 'self';
  font-src 'self';
  connect-src 'self';
  base-uri 'self';
  form-action 'self';
  frame-ancestors 'none';
  object-src 'none';
  upgrade-insecure-requests

中程度(典型的なSPA)

Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'unsafe-inline' 'unsafe-eval';
  style-src 'self' 'unsafe-inline';
  img-src 'self' data: blob: https:;
  font-src 'self' https://fonts.gstatic.com;
  connect-src 'self' https://api.example.com wss://ws.example.com;
  frame-ancestors 'self'

Google Analytics付き

Content-Security-Policy:
  default-src 'self';
  script-src 'self' https://www.googletagmanager.com https://www.google-analytics.com;
  img-src 'self' https://www.google-analytics.com https://www.googletagmanager.com;
  connect-src 'self' https://www.google-analytics.com https://analytics.google.com

実装方法

Nginx

add_header Content-Security-Policy "default-src 'self'; script-src 'self'" always;

Apache

Header set Content-Security-Policy "default-src 'self'; script-src 'self'"

Express.js

// Using helmet middleware (recommended)
const helmet = require('helmet');
app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'", "https://cdn.example.com"],
    styleSrc: ["'self'", "'unsafe-inline'"],
    imgSrc: ["'self'", "data:", "https:"],
  }
}));

// Or manually
app.use((req, res, next) => {
  res.setHeader('Content-Security-Policy',
    "default-src 'self'; script-src 'self'");
  next();
});

HTMLメタタグ

<meta http-equiv="Content-Security-Policy"
  content="default-src 'self'; script-src 'self'">

よくある間違い

間違い影響修正
スクリプトにunsafe-inline使用XSS保護が無効にnonceまたはhashを使用
unsafe-eval使用eval()を許可eval()を避けるよう改修
script-srcにワイルドカード任意ドメインのスクリプト許可特定ドメインをホワイトリスト
インラインスタイルの考慮漏れCSS-in-JSがブロックstyle-srcにunsafe-inlineかnonce
レポートオンリーでのテスト省略サイト機能が壊れる必ずレポートオンリーから開始
base-uri未設定baseタグ注入を許可base-uri 'self'を追加

FAQ

CSPはどんな攻撃を防ぎますか?

主にXSS攻撃を防ぎます。また、クリックジャッキング、データ注入、混合コンテンツ問題も防ぎます。

CSPは入力検証の代わりになりますか?

いいえ。CSPは多層防御の一つです。入力の検証とサニタイズは引き続き必要です。

インラインスクリプトでCSPを使うには?

nonce(ランダムトークン)またはhash(SHA-256)を使用します。unsafe-inlineは避けてください。

CSPはサイトを遅くしますか?

いいえ。CSPはブラウザが実行し、パフォーマンスへの影響は無視できる程度です。

𝕏 Twitterin LinkedIn
この記事は役に立ちましたか?

最新情報を受け取る

毎週の開発ヒントと新ツール情報。

スパムなし。いつでも解除可能。

Try These Related Tools

🛡️CSP Header Generator.ht.htaccess GeneratorNXNginx Config Generator🏷️Meta Tag Generator

Related Articles

Docker Compose チートシート:サービス、ボリューム、ネットワーク

Docker Compose リファレンス:サービス定義、ボリューム、ネットワーク、環境変数、スタック例。

CORSエラーの直し方:完全トラブルシューティングガイド

CORSエラーをステップバイステップで解決。Access-Control-Allow-Origin、プリフライト、Express/Nginx設定を解説。