DevToolBoxFREE
BlogAdvertise

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
この記事は役に立ちましたか?

Stay Updated

Get weekly dev tips and new tool announcements.

No spam. Unsubscribe anytime.

Partner Picks

Sponsor this article

Place your product next to this developer topic with tracked clicks.

Ask about article sponsorship

This site uses cookies for analytics and to display ads. By continuing to browse, you agree. Privacy Policy