コンテンツセキュリティポリシー (CSP) は、クロスサイトスクリプティング (XSS) やデータインジェクション攻撃などのような、特定の種類の攻撃を検知し、影響を軽減するために追加できるセキュリティレイヤーです。これらの攻撃はデータの窃取からサイトの改ざん、マルウェアの拡散に至るまで、様々な目的に用いられます。

CSP は完全な後方互換性を保って設計されています (ただし、 CSP 2 については後方互換性が無い点もあり、明示的に記述されています。詳細はこちらの 1.1 章を参照してください)。そのため、 CSP に未対応のブラウザーでも CSP 実装済のサーバーと通信でき、逆もまた同様です。 CSP 未対応のブラウザーは単に CSP を無視し、ウェブコンテンツにはこれまで通り標準の同一オリジンポリシーを適用します。 CSP ヘッダーを送信しないサーバーに対しても、ブラウザーは同様に標準の 同一オリジンポリシー を適用します。

CSP を有効にするには、ウェブサーバーから Content-Security-Policy HTTP ヘッダーを返すように設定する必要があります (X-Content-Security-Policy ヘッダーに関する記述が時々ありますが、これは古いバージョンのものであり、今日このヘッダーを指定する必要はありません)。

他にも、 <meta> 要素を用いてポリシーを指定することも可能です。 例えば: <meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

脅威

クロスサイトスクリプティングの軽減

CSP の第一の目的は XSS 攻撃の軽減と報告です。 XSS 攻撃とは、サーバーから取得したコンテンツをブラウザーが信頼する性質を悪用した攻撃です。ブラウザーはコンテンツの送信元を信頼するため、たとえ実際の送信元が見かけ上とは異なっていたとしても、悪意あるスクリプトが被害者のブラウザー上で実行されてしまいます。

サーバー管理者が CSP を利用する場合、実行を許可するスクリプトの正しいドメインをブラウザーに向けて指定することにより、 XSS の発生する箇所を削減・根絶することができます。 CSP をサポートするブラウザーは、サーバーから指定されたホワイトリストに載っているドメインのスクリプトのみ実行し、他のスクリプトはすべて無視します (インラインスクリプトや HTML 属性値のイベントハンドラも無視する対象に含まれます)。

究極的な防衛策として、スクリプトを決して実行させたくないサイトは、スクリプトの実行を全面的に拒否することも可能です。

パケット盗聴攻撃の軽減

取得するコンテンツのドメインを制限することに加えて、サーバーは通信に使うプロトコルを指定することも可能です。例えば、 (セキュリティの観点からはこれが理想的ですが) すべてのコンテンツを HTTPS で取得されるようにサーバーから指定することが出来ます。データ通信におけるセキュリティ戦略を完全なものとするには、HTTPS 通信を強制するだけではなく、すべての Cookie に secure フラグ を付けたり、HTTP ページから対応する HTTPS ページへの自動リダイレクトを整備することも必要です。また、ブラウザーが暗号化された通信路のみを用いてサイトに接続することを保証するため、Strict-Transport-Security HTTP ヘッダーを利用することも可能です。

CSP の適用

コンテンツセキュリティポリシーを適用するには、該当するウェブページについて Content-Security-Policy HTTP ヘッダーを返すようにし、その値にはユーザエージェントに読み込ませたいリソースの情報を指定します。例えば、画像のアップロード・表示を行うページの場合、画像の出元は任意の場所で構いませんが、フォームの action 属性値は特定のエンドポイントに制限する必要があります。コンテンツセキュリティポリシーを適切に設計すれば、クロスサイトスクリプティング攻撃に対する耐性を高めることができます。この記事では、適切なヘッダーの作成方法と記述例を紹介します。

ポリシーの設定

ポリシーの設定には Content-Security-Policy HTTP ヘッダーを以下のように用います。

Content-Security-Policy: policy

policy の箇所には、適用したいコンテンツセキュリティポリシーを表すディレクティブから構成される文字列が入ります。

ポリシーの記述

ポリシーはポリシーディレクティブを列挙することで表現します。このポリシーディレクティブは、特定の種類のリソースや、ポリシーの適用範囲をそれぞれ表すものです。ポリシーには default-src ディレクティブを指定するべきでしょう。このディレクティブは、ポリシーについて特に指定のないリソースに対するフォールバックの役目を果たします (一覧については default-src の説明を参照してください)。また、インラインスクリプトや eval() の実行を防ぐには default-srcscript-src を指定する必要があります。さらに、<style> 要素や style 属性によるインラインスタイルの適用を防ぐには default-srcstyle-src の指定が必要となります。

一般的な適用例

この章では、一般的なセキュリティポリシーの適用例を示します。

例 1

サイト管理者が、すべてのコンテンツをサイト自身のドメイン (サブドメインを除く) から取得させたい場合。

Content-Security-Policy: default-src 'self'

例 2

サイト管理者が、信頼されたドメインとそのすべてのサブドメインからのコンテンツを許可したい場合 (CSPがセットされたドメインと同一とは限らない)。

Content-Security-Policy: default-src 'self' *.trusted.com

例 3

サイト管理者がウェブアプリのユーザーに、任意のドメインからの画像読み込みを許可したい場合。ただし、音声や動画は信頼された配信元からのものだけに制限し、すべてのスクリプトは、信頼されたコードをホストする特定のサーバーのみに制限する。

Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com

この例では、コンテンツのデフォルト設定としてドキュメント自身のホストのみを許可していますが、以下の例外を認めています。

  • 画像は任意の場所から読み込まれます (ワイルドカード "*" による指定に注意)。
  • メディアは media1.com と media2.com のものだけが許可されます (ただしサブドメインは許可されません)。
  • 実行可能なスクリプトは userscripts.example.com のものだけ許可されます。

例 4

サイト管理者がオンラインバンキングのウェブサイトについて、リクエスト時の盗聴攻撃を防ぐため、すべてのコンテンツを SSL で読み込むようにしたい場合。

Content-Security-Policy: default-src https://onlinebanking.jumbobank.com

この例では、ドメインを単一オリジン onlinebanking.jumbobank.com のみに制限し、かつドキュメントへのアクセスを HTTPS のみに制限しています。

例 5

サイト管理者がウェブメールサイトについて、メール内の HTML を許可し、任意のドメインから画像の読み込みを許可するが、JavaScript や他に危険性のあるコンテンツは許可したくない場合。

Content-Security-Policy: default-src 'self' *.mailsite.com; img-src *

この例では、 script-src を指定していないことに注意してください。この CSP を適用したサイトは、スクリプトに関して default-src ディレクティブの設定を適用します。つまり、スクリプトは元のサーバーのものだけ読み込まれます。

ポリシーのテスト

本番環境への適用をスムーズに行うため、CSP は report-only モードで動作させることが可能です。このモードの場合、ポリシーによるブロックは行われず、指定した URI へポリシー違反の内容が報告されます。また、新しいポリシーを本番環境に適用する前に試験運用する際にも report-only モードは利用できます。

ポリシーを report-only モードで動作させるには、以下のようにポリシーを Content-Security-Policy-Report-Only HTTP ヘッダーに指定します。

Content-Security-Policy-Report-Only: policy 

同じレスポンス中に Content-Security-Policy-Report-Only ヘッダーと Content-Security-Policy ヘッダーが存在した場合、どちらのポリシーも考慮されます。Content-Security-Policy ヘッダーに指定したポリシーについてはブロックが行われ、Content-Security-Policy-Report-Only ヘッダーに指定したポリシーは報告のみが行われます。

報告機能の利用

既定では、違反内容は報告されません。違反内容の報告機能を有効にするには report-uri ポリシーディレクティブを指定し、報告先の URI を 1 つ以上指定する必要があります。

Content-Security-Policy: default-src 'self'; report-uri http://reportcollector.example.com/collector.cgi

URI を指定したら報告を受け取るサーバーを立ち上げます。受信した内容は適切に感じるどんな方法でも保存・処理することができます。

 

違反内容は以下のデータを含んだ JSON オブジェクトで送信されます。

blocked-uri
コンテンツセキュリティポリシーによって読み込みがブロックされたリソースの URI。blocked-uridocument-uri とは異なるオリジンだった場合、blocked-uri はスキーム・ホスト・ポートのみを含むように切り詰められます。
disposition
"enforce""reporting" のいずれかで、Content-Security-Policy-Report-Only ヘッダーか Content-Security-Policy ヘッダーのどちらが使われているかで決まる。
document-uri
違反が生じたドキュメントの URI。
effective-directive
実行により違反を起こしたディレクティブです。
original-policy
Content-Security-Policy HTTP ヘッダーに元々指定されていたポリシー。
referrer
違反が生じたドキュメントのリファラー。
script-sample
違反を起こしたインラインスクリプト、イベントハンドラー、スタイルの最初の 40 文字、
status-code
グローバルオブジェクトが初期化されたリソースの HTTP ステータスコード。
violated-directive
違反したポリシーセクションの名前。

違反報告の例

http://example.com/signup.html というページを例に考えます。ここでは次のようなポリシーを指定しており、cdn.example.com のスタイルシートのみを許可しています。

Content-Security-Policy: default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports

signup.html の内容は次の通りです。

<!DOCTYPE html>
<html>
  <head>
    <title>Sign Up</title>
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    ... Content ...
  </body>
</html>

間違いがあることにお気付きでしょうか?スタイルシートの読み込みは cdn.example.com からのみに制限されていますが、実際には自身のドメイン (http://example.com) から読み込もうとしています。このドキュメントを閲覧した際には、次のような違反内容が http://example.com/_/csp-reports へ POST リクエストで送信されます。

{
  "csp-report": {
    "document-uri": "http://example.com/signup.html",
    "referrer": "",
    "blocked-uri": "http://example.com/css/style.css",
    "violated-directive": "style-src cdn.example.com",
    "original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports"
  }
}

ご覧の通り、blocked-uri には違反の原因となったリソースのフルパスが記録されています。ただし、必ずフルパスが記録されるとは限りません。例えば、 signup.htmlhttp://anothercdn.example.com/stylesheet.css から CSS を読み込もうとした場合、blocked-uri にはフルパスではなくオリジンのみ (http://anothercdn.example.com) が記録されます。この一見不思議な挙動は CSP の仕様書に 説明されています。手短に言うと、この挙動はクロスオリジンのリソースに関する機密情報の漏えいを防ぐために規定されています。

ブラウザーの対応

Update compatibility data on GitHub
デスクトップモバイル
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeEdge MobileAndroid 版 FirefoxAndroid 版 OperaiOS 版 SafariSamsung Internet
Content-Security-PolicyChrome 完全対応 25
補足
完全対応 25
補足
補足 Implemented as X-Webkit-CSP header in Chrome 14.
Edge 完全対応 14Firefox 完全対応 23
補足
完全対応 23
補足
補足 Implemented as X-Content-Security-Policy header in Firefox 4.
IE 完全対応 10
補足
完全対応 10
補足
補足 Implemented as X-Content-Security-Policy header, only supporting 'sandbox' directive.
Opera 完全対応 15Safari 完全対応 7
補足
完全対応 7
補足
補足 Implemented as X-Webkit-CSP header in Safari 6.
WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile 完全対応 ありFirefox Android 完全対応 23Opera Android ? Safari iOS 完全対応 7.1
補足
完全対応 7.1
補足
補足 Implemented as X-Webkit-CSP header in iOS 5.1.
Samsung Internet Android 完全対応 あり
base-uriChrome 完全対応 40Edge 未対応 なしFirefox 完全対応 35IE 未対応 なしOpera 完全対応 27Safari 完全対応 10WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile 未対応 なしFirefox Android 完全対応 35Opera Android ? Safari iOS 完全対応 9.3Samsung Internet Android 完全対応 あり
block-all-mixed-contentChrome 完全対応 ありEdge ? Firefox 完全対応 48IE 未対応 なしOpera 完全対応 ありSafari ? WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile ? Firefox Android 完全対応 48Opera Android ? Safari iOS ? Samsung Internet Android 完全対応 あり
child-src
非推奨
Chrome 完全対応 40Edge 完全対応 15Firefox 完全対応 45IE 未対応 なしOpera 完全対応 27Safari 完全対応 10WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile 未対応 なしFirefox Android 完全対応 45Opera Android ? Safari iOS 完全対応 9.3Samsung Internet Android 完全対応 あり
connect-srcChrome 完全対応 25Edge 完全対応 14Firefox 完全対応 23
補足
完全対応 23
補足
補足 Prior to Firefox 50, ping attributes of <a> elements weren't covered by connect-src.
IE 未対応 なしOpera 完全対応 15Safari 完全対応 7WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile ? Firefox Android 完全対応 23Opera Android ? Safari iOS 完全対応 7.1Samsung Internet Android 完全対応 あり
default-srcChrome 完全対応 25Edge 完全対応 14Firefox 完全対応 23IE 未対応 なしOpera 完全対応 15Safari 完全対応 7WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile ? Firefox Android 完全対応 23Opera Android ? Safari iOS 完全対応 7.1Samsung Internet Android 完全対応 あり
disown-opener
実験的
Chrome 未対応 なしEdge 未対応 なしFirefox 未対応 なしIE 未対応 なしOpera 未対応 なしSafari 未対応 なしWebView Android 未対応 なしChrome Android 未対応 なしEdge Mobile 未対応 なしFirefox Android 未対応 なしOpera Android 未対応 なしSafari iOS 未対応 なしSamsung Internet Android 未対応 なし
font-srcChrome 完全対応 25Edge 完全対応 14Firefox 完全対応 23IE 未対応 なしOpera 完全対応 15Safari 完全対応 7WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile ? Firefox Android 完全対応 23Opera Android ? Safari iOS 完全対応 7.1Samsung Internet Android 完全対応 あり
form-actionChrome 完全対応 40Edge 完全対応 15Firefox 完全対応 36IE 未対応 なしOpera 完全対応 27Safari 完全対応 10WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile 未対応 なしFirefox Android 完全対応 36Opera Android ? Safari iOS 完全対応 9.3Samsung Internet Android 完全対応 あり
frame-ancestorsChrome 完全対応 40Edge 完全対応 15Firefox 完全対応 33
補足
完全対応 33
補足
補足 Before Firefox 58, frame-ancestors is ignored in Content-Security-Policy-Report-Only.
IE 未対応 なしOpera 完全対応 26Safari 完全対応 10WebView Android ? Chrome Android 完全対応 ありEdge Mobile 未対応 なしFirefox Android 完全対応 33
補足
完全対応 33
補足
補足 Before Firefox for Android 58, frame-ancestors is ignored in Content-Security-Policy-Report-Only.
Opera Android ? Safari iOS 完全対応 9.3Samsung Internet Android 完全対応 あり
frame-srcChrome 完全対応 25Edge 完全対応 14Firefox 完全対応 23IE 未対応 なしOpera 完全対応 15Safari 完全対応 7WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile ? Firefox Android 完全対応 23Opera Android ? Safari iOS 完全対応 7.1Samsung Internet Android 完全対応 あり
img-srcChrome 完全対応 25Edge 完全対応 14Firefox 完全対応 23IE 未対応 なしOpera 完全対応 15Safari 完全対応 7WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile ? Firefox Android 完全対応 23Opera Android ? Safari iOS 完全対応 7.1Samsung Internet Android 完全対応 あり
manifest-srcChrome 完全対応 ありEdge 未対応 なしFirefox 完全対応 41IE 未対応 なしOpera 完全対応 ありSafari 未対応 なしWebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile 未対応 なしFirefox Android 完全対応 41Opera Android ? Safari iOS 未対応 なしSamsung Internet Android 完全対応 あり
media-srcChrome 完全対応 25Edge 完全対応 14Firefox 完全対応 23IE 未対応 なしOpera 完全対応 15Safari 完全対応 7WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile ? Firefox Android 完全対応 23Opera Android ? Safari iOS 完全対応 7.1Samsung Internet Android 完全対応 あり
navigate-to
実験的
Chrome 未対応 なしEdge 未対応 なしFirefox 未対応 なしIE 未対応 なしOpera 未対応 なしSafari 未対応 なしWebView Android 未対応 なしChrome Android 未対応 なしEdge Mobile 未対応 なしFirefox Android 未対応 なしOpera Android 未対応 なしSafari iOS 未対応 なしSamsung Internet Android 未対応 なし
object-srcChrome 完全対応 25Edge 完全対応 14Firefox 完全対応 23IE 未対応 なしOpera 完全対応 15Safari 完全対応 7WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile ? Firefox Android 完全対応 23Opera Android ? Safari iOS 完全対応 7.1Samsung Internet Android 完全対応 あり
plugin-typesChrome 完全対応 40Edge 完全対応 15Firefox 未対応 なし
補足
未対応 なし
補足
補足 See bug 1045899.
IE 未対応 なしOpera 完全対応 27Safari 完全対応 10WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile 未対応 なしFirefox Android 未対応 なしOpera Android ? Safari iOS 完全対応 9.3Samsung Internet Android 完全対応 あり
referrer
非推奨非標準
Chrome 未対応 33 — 56Edge 未対応 なしFirefox 未対応 37 — 62IE 未対応 なしOpera 未対応 ? — 43Safari 未対応 なしWebView Android 未対応 37 — 56Chrome Android 未対応 33 — 56Edge Mobile 未対応 なしFirefox Android 未対応 37 — 62Opera Android 未対応 ? — 43Safari iOS 未対応 なしSamsung Internet Android 完全対応 あり
report-sample
実験的
Chrome 完全対応 59Edge ? Firefox ? IE ? Opera 完全対応 46Safari ? WebView Android 完全対応 59Chrome Android 完全対応 59Edge Mobile ? Firefox Android ? Opera Android 完全対応 46Safari iOS ? Samsung Internet Android 完全対応 7.0
report-toChrome 未対応 なしEdge 未対応 なしFirefox 未対応 なしIE 未対応 なしOpera 未対応 なしSafari 未対応 なしWebView Android 未対応 なしChrome Android 未対応 なしEdge Mobile 未対応 なしFirefox Android 未対応 なしOpera Android 未対応 なしSafari iOS 未対応 なしSamsung Internet Android 未対応 なし
report-uri
非推奨
Chrome 完全対応 25Edge 完全対応 14Firefox 完全対応 23IE 未対応 なしOpera 完全対応 15Safari 完全対応 7WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile ? Firefox Android 完全対応 23Opera Android ? Safari iOS 完全対応 7.1Samsung Internet Android 完全対応 あり
require-sri-for
実験的
Chrome 完全対応 54Edge 未対応 なしFirefox 完全対応 49
無効
完全対応 49
無効
無効 From version 49: this feature is behind the security.csp.experimentalEnabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
IE 未対応 なしOpera 完全対応 41Safari 未対応 なしWebView Android 完全対応 54Chrome Android 完全対応 54Edge Mobile 未対応 なしFirefox Android 完全対応 49
無効
完全対応 49
無効
無効 From version 49: this feature is behind the security.csp.experimentalEnabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
Opera Android 完全対応 41Safari iOS 未対応 なしSamsung Internet Android 完全対応 6.0
sandboxChrome 完全対応 25Edge 完全対応 14Firefox 完全対応 50IE 完全対応 10Opera 完全対応 15Safari 完全対応 7WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile ? Firefox Android 完全対応 50Opera Android ? Safari iOS 完全対応 7.1Samsung Internet Android 完全対応 あり
script-srcChrome 完全対応 25Edge 完全対応 14Firefox 完全対応 23IE 未対応 なしOpera 完全対応 15Safari 完全対応 7WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile ? Firefox Android 完全対応 23Opera Android ? Safari iOS 完全対応 7.1Samsung Internet Android 完全対応 あり
strict-dynamicChrome 完全対応 52Edge 未対応 なしFirefox 完全対応 52IE 未対応 なしOpera 完全対応 39Safari 未対応 なしWebView Android 完全対応 52Chrome Android 完全対応 52Edge Mobile 未対応 なしFirefox Android 未対応 なしOpera Android 完全対応 39Safari iOS 未対応 なしSamsung Internet Android 完全対応 6.0
style-srcChrome 完全対応 25Edge 完全対応 14Firefox 完全対応 23IE 未対応 なしOpera 完全対応 15Safari 完全対応 7WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile ? Firefox Android 完全対応 23Opera Android ? Safari iOS 完全対応 7.1Samsung Internet Android 完全対応 あり
upgrade-insecure-requestsChrome 完全対応 43Edge 未対応 なし
補足
未対応 なし
補足
補足 Under consideration for future release.
Firefox 完全対応 42IE 未対応 なしOpera 完全対応 30Safari 完全対応 10.1WebView Android 完全対応 43Chrome Android 完全対応 43Edge Mobile 未対応 なしFirefox Android 完全対応 42Opera Android 完全対応 30Safari iOS 完全対応 10.3Samsung Internet Android 完全対応 4.0
worker-srcChrome 完全対応 59
補足
完全対応 59
補足
補足 Chrome 59 and higher skips the deprecated child-src directive.
Edge 未対応 なしFirefox 完全対応 58IE 未対応 なしOpera 完全対応 48Safari 未対応 なしWebView Android 完全対応 59
補足
完全対応 59
補足
補足 Chrome 59 and higher skips the deprecated child-src directive.
Chrome Android 完全対応 59
補足
完全対応 59
補足
補足 Chrome 59 and higher skips the deprecated child-src directive.
Edge Mobile 未対応 なしFirefox Android 完全対応 58Opera Android 完全対応 48Safari iOS 未対応 なしSamsung Internet Android 完全対応 7.0

凡例

完全対応  
完全対応
未対応  
未対応
実装状況不明  
実装状況不明
実験的。動作が変更される可能性があります。
実験的。動作が変更される可能性があります。
非標準。ブラウザー間の互換性が低い可能性があります。
非標準。ブラウザー間の互換性が低い可能性があります。
非推奨。新しいウェブサイトでは使用しないでください。
非推奨。新しいウェブサイトでは使用しないでください。
実装ノートを参照してください。
実装ノートを参照してください。
ユーザーが明示的にこの機能を有効にしなければなりません。
ユーザーが明示的にこの機能を有効にしなければなりません。

一部のバージョンの Safari には、コンテンツセキュリティポリシーヘッダーが設定されていて Same Origin ヘッダーがないと、ブラウザーが自分自身でホストされたコンテンツやオフサイトコンテンツをブロックし、コンテンツセキュリティポリシーがそのコンテンツを許可していないという誤った報告をするという顕著な非互換があります。

関連情報

ドキュメントのタグと貢献者

このページの貢献者: mfuji09, Uemmra3, jwhitlock, hashedhyphen, hamasaki, yyss, Marsf
最終更新者: mfuji09,