MDN wants to talk to developers like you: https://qsurvey.mozilla.com/s3/8d22564490d8

Content Security Policy (CSP)

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

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

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

他にも、 <meta> 要素を用いてポリシーを指定することも可能です。

脅威

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

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

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

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

パケット盗聴攻撃の軽減

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

CSP の適用

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

ポリシーの設定

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

Content-Security-Policy: policy

policy の箇所には、適用したい Content Security Policy を表すディレクティブから構成される文字列が入ります。

ポリシーの記述

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

一般的な適用例

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

例 1

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

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

例 2

信頼されたドメインとそのすべてのサブドメイン(ワイルドカードで指定)からのコンテンツを許可したい場合。

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

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

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

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

例 5

web メールサイトについて、メール内の 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 ディレクティブが指定されていれば、CSP をサポートするブラウザは動作モードに関係なく違反内容を報告します。

報告機能の利用

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

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

URI を指定したら報告を受け取るサーバを立ち上げます。受信した内容は自由に保存・処理することができます。

違反報告の構文

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

document-uri
違反が生じたドキュメントの URI。
referrer
違反が生じたドキュメントのリファラ。
blocked-uri
Content Security Policy によって読み込みがブロックされたリソースの URI。blocked-uridocument-uri とは異なるオリジンだった場合、blocked-uri はスキーム・ホスト・ポートのみを含むように切り詰められます。
violated-directive
違反したポリシーセクションの名前。
original-policy
Content-Security-Policy HTTP ヘッダに元々指定されていたポリシー。

違反報告の例

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.html http://anothercdn.example.com/stylesheet.css から CSS を読み込もうとした場合、blocked-uri にはオリジンのみ(http://anothercdn.example.com)が記録されます。この一見不思議な挙動は CSP の仕様書に 説明されています。手短に言うと、この挙動はクロスオリジンのリソースに関する機密情報の漏えいを防ぐために規定されています。この点については、仕様書でさえも 違反報告の例 において間違っているので注意が必要です(blocked-uri は "http://evil.example.com" となるべきです)。

ブラウザ実装状況

機能 Chrome Edge Firefox Internet Explorer Opera Safari Servo
Content-Security-Policy2511423.021031574?
Content-Security-Policy-Report-Only251423.010157?
機能 Android Chrome for Android Edge Mobile Firefox for Android IE Mobile Opera Mobile Safari Mobile
Content-Security-Policy4.4(有り)(有り)23.0??7.15
Content-Security-Policy-Report-Only4.4(有り)(有り)23.0??7.1

1. Implemented as X-Webkit-CSP header in Chrome 14.

2. Implemented as X-Content-Security-Policy header in Firefox 4.

3. Implemented as X-Content-Security-Policy header, only supporting 'sandbox' directive.

4. Implemented as X-Webkit-CSP header in Safari 6.

5. Implemented as X-Webkit-CSP header in iOS 5.1.

関連情報

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

タグ: 
 このページの貢献者: momoiroshikibu, hashedhyphen, hamasaki, takashi, ethertank, Marsf
 最終更新者: momoiroshikibu,