この文書は2016年以降更新されていません
CSP に関するチートシート
CSP (コンテンツセキュリティポリシー) は、W3C による重要な標準規格であり、さまざまなコンテンツインジェクション攻撃 (クロスサイトスクリプティング (XSS) など) の防止を目的としています。
はじめに
CSP (コンテンツセキュリティポリシー) は、効果的な "多層防御" の技法であり、コンテンツインジェクション攻撃への対抗策として使用されます。これは宣言型ポリシーであり、正当な読み込み元のソースをユーザーエージェントに通知するものです。
CSP は、Mozilla により Firefox バージョン 4 に導入され、標準規格として採用され、採用率と機能性は拡大しています。
このドキュメントでは、各種の懸念事項に対処するために、さまざまな状況下で CSP を使用する方法についてのガイダンスを提供します。
参考資料
CSP 標準規格の仕様書は、次の場所にあります。
- 最新改訂版 - https://w3c.github.io/webappsec/specs/content-security-policy/
- 最新バージョン (CSP2) - http://www.w3.org/TR/CSP2/
- CSP 1.0 - http://www.w3.org/TR/2012/CR-CSP-20121115/
CSP の基本
CSP は、一連のディレクティブで構成されています。また、CSP は 2 つの大幅改訂を経て進化しています。ほとんどのブラウザーは 1.0 をサポートしており、CSP2 の採用率も徐々に増加しています。
HTTP ヘッダー
次に、CSP のヘッダーを示します。
- Content-Security-Policy: W3C 仕様の標準ヘッダー。Firefox 23 以上、Chrome 25 以上、および Opera 19 以上でサポート。
- Content-Security-Policy-Report-Only: W3C 仕様の標準ヘッダー。Firefox 23 以上、Chrome 25 以上、および Opera 19 以上でサポート。このポリシーでは、ブロックを行いません (フェイルオープン)。レポートは、report-uri ディレクティブで指定した URL に送信されます。このヘッダーは、多くの場合、CSP をブロックモード (フェイルクローズ) で利用する前段階として使用されます。
- X-Content-Security-Policy または X-WebKit-CSP は、使用しないでください。これらの実装は廃止されていて (Firefox 23 以上、Chrome 25 以上)、制限があり、一貫性がなく、非常に多くのバグが含まれています。
ディレクティブ
次に、ディレクティブの一覧と簡単な説明を示します。
CSP 1.0 仕様
- connect-src (d) - 保護対象リソースがスクリプトインターフェイス (XMLHttpRequest オブジェクトの send() メソッドなど) を使用して読み込むことのできる URL を制限します。
- font-src (d) - 保護対象リソースがフォントの読み込み元にできる場所を制限します
- img-src (d) - 保護対象リソースがイメージの読み込み元にできる場所を制限します
- media-src (d) - 保護対象リソースがビデオ、オーディオ、および関連テキストトラックの読み込み元にできる場所を制限します
- object-src (d) - 保護対象リソースがプラグインの読み込み元にできる場所を制限します
- script-src (d) - 保護対象リソースが実行できるスクリプトを制限します。インラインスクリプト、および eval に対する追加の制限。ハッシュおよび nonce サポートのための CSP2 における追加ディレクティブ
- style-src (d) - 保護対象リソースにユーザーが適用できるスタイルを制限します。インラインおよび eval に対する追加の制限。
- default-src - (d) の付いたディレクティブをすべて有効にします
- frame-src - 保護対象リソースが埋め込めるフレームの供給元を制限します。CSP2 では廃止されている点に注意してください
- report-uri - ポリシー違反に関するレポートをユーザーエージェントが送信する URL を指定します
- sandbox - ユーザーエージェントが保護対象リソースに適用する HTML サンドボックスポリシーを指定します。1.0 ではオプションです
CSP2 の新しいディレクティブ
- form-action - HTML フォーム要素のアクションとして使用できる URL を制限します
- frame-ancestors - frame、iframe、object、embed または applet 要素を使用するか、HTML 以外のリソースの同等の機能を使用して、ユーザーエージェントがリソースを埋め込めるようにするかどうかを示します
- plugin-types - 埋め込み可能なリソースのタイプを限定することで、保護対象リソースが起動できるプラグインのセットを制限します
- base-uri - ドキュメントのベース URL の指定に使用できる URL を制限します
- child-src (d) - 入れ子になったブラウジングコンテキストと Worker の実行コンテキストの作成を制御します
CSP サンプルポリシー
基本 CSP ポリシー
このポリシーでは、すべての既定レベルのディレクティブに対応する生成元ドメインからのリソースのみを許可し、インラインのスクリプト / スタイルの実行を許可しません。このような制限をアプリケーションと機能に適用して、このポリシーを実施していると、攻撃対象領域は大幅に減少します。これは、ほとんどの最新ブラウザーで動作します。
最も基本的なポリシーは、以下を前提としています。
- すべてのリソースは、それらを参照するドキュメントと同じドメインでホストされている
- スクリプトおよびスタイルリソースのインラインまたは eval は存在しない
Content-Security-Policy: default-src 'self'
さらに制限を厳しくする場合は、以下のようにできます。
Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self';
このポリシーは、同じオリジンからのイメージ、スクリプト、AJAX、および CSS を許可し、その他のリソース (オブジェクト、フレーム、メディアなど) の読み込みを禁止します。(http://content-security-policy.com/ を参照)
混在コンテンツポリシー
混在コンテンツ (https 経由でロードされたドキュメントから、http 経由でリソースが読み込まれること) を防止するために、ディレクティブ値として値 "https:" を使用できます。
たとえば、次のようにします。
Content-Security-Policy: default-src https:; connect-src https:; font-src https: data:; frame-src https:; img-src https: data:; media-src https:; object-src https:; script-src 'unsafe-inline' 'unsafe-eval' https:; style-src 'unsafe-inline' https:;
これは、2014 年 10 月時点で Twitter において使用されていたものです。このポリシーでは、混在コンテンツを防止し、font-src と img-src でスキーマ "data:" を許可し、script-src の unsafe-inline と unsafe-eval、および style-src の unsafe-inline を許可します。(参照: https://twittercommunity.com/t/blocking-mixed-content-with-content-security-policy/26375)
混在コンテンツは、アクティブとパッシブの 2 つのカテゴリに分けられます。パッシブコンテンツは、 "ページ上の他のリソースと直接対話できないリソース、または他のリソースを変更できないリソース (イメージ、フォント、オーディオ、ビデオなど)" で構成されます。アクティブコンテンツは "ユーザーが対話しているリソースを何らかの方法で直接操作できるコンテンツ" です。(http://www.w3.org/TR/2014/WD-mixed-content-20140722)
Content-Security-Policy: img-src https: data:; font-src https: data:; media-src https:;
これは、パッシブな混在コンテンツのみをブロックする例です。
Content-Security-Policy: script-src https:; style-src https:; object-src https:; connect-src https:; frame-src https:;
これは、アクティブな混在コンテンツのみをブロックする例です。
クリックジャッキングの防止
クリックジャッキング防止のための確立された方法では、X-Frame-Options
ヘッダーを使用します (参照: クリックジャッキング対策に関するチートシート)。ただし、CSP 2.0 には新しいディレクティブ frame-ancestors
があります。
コンテンツのフレーム内表示を完全に防止するには、以下を使用します。
Content-Security-Policy: frame-ancestors 'none'
自分のサイトのみ許可するには、以下を使用します。
Content-Security-Policy: frame-ancestors 'self'
信頼されたドメイン (my-trusty-site.com) を許可するには、以下のようにします。
Content-Security-Policy: frame-ancestors my-trusty-site.com
サポートについて、少し説明します。まだすべてのブラウザーでサポートされているわけではありません。Chrome 40 以上および FF 35 以上はサポートしていますが、既定では X-Frame-Options の設定が優先されます (存在する場合)。仕様では、CSP を優先する必要があります。https://w3c.github.io/webappsec/specs/content-security-policy/#frame-ancestors-and-frame-options
また、次の事項にも注意が必要です (CSP 仕様からの抜粋):
frame-ancestors ディレクティブは、ポリシーをモニターしているとき、および meta 要素で定義されたポリシーに含まれているときには、無視する必要がある。
つまり、このディレクティブは CSP が <meta> タグに含まれているとき、および Content-Security-Policy-Report-Only を使用しているときには機能しないということです。
レポートが生成されると、blocked-uri はページと同じオリジンである場合にのみ値を持ちます。
インラインコードのリファクタリング
既定では、CSP は HTML ソースにインライン配置された未署名の JavaScript コードをすべて無効にします。以下に例を示します。
<script>var foo = "314"<script>
インラインコードは、CSP ヘッダー内でそのコードの SHA256 ハッシュを指定することで有効化できます。
Content-Security-Policy: script-src 'sha256-gPMJwWBMWDx0Cm7ZygJKZIU2vZpiYvzUQjl5Rh37hKs='
この特定のスクリプトのハッシュは、次のコマンドを使用して計算できます。
echo -n 'var foo = "314"' | openssl sha256 -binary | openssl base64
一部のブラウザー (Chrome など) は、未署名のスクリプトをブロックするときに、スクリプトのハッシュを JavaScript コンソールの警告で表示します。
インラインコードはそのまま別の JavaScript ファイルに移動することもできます。
<script>var foo = "314"<script>
これを、次のようにファイルを参照する形にします。
<script src="app.js"></script>
この 'app.js' に、コード 'var foo = "314"' を含めます。
インラインコードの制限は、インラインイベントハンドラーにも適用されるため、以下のコンストラクトは CSP でブロックされます。
<button id="button1" onclick="doSomething()">
これは、'addEventListener' 呼び出しで置き換える必要があります。
document.getElementById("button1").addEventListener('click', doSomething);
それから、以下のようなインラインスクリプトの変数代入式
<script>var foo = "314";<script>
HTML5 のカスタムデータ属性を使いましょう。以下のように値を設定し、
<body data-foo="314”> ... </body>
以下のようにして、この値にアクセスします。
var itemID = document.body.getAttribute("data-foo”);
Authors and Primary Editors
- Neil Mattatall - neil[at]owasp.org
- Denis Mello - ddtaxe
- Boris Chen
Other Cheatsheets
OWASP Cheat Sheets Project Homepage
Developer Cheat Sheets (Builder)
- Authentication Cheat Sheet (Spanish)
- Choosing and Using Security Questions Cheat Sheet
- Clickjacking Defense Cheat Sheet
- C-Based Toolchain Hardening Cheat Sheet
- Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet
- Cryptographic Storage Cheat Sheet
- DOM based XSS Prevention Cheat Sheet
- Forgot Password Cheat Sheet
- HTML5 Security Cheat Sheet
- Input Validation Cheat Sheet
- JAAS Cheat Sheet
- Logging Cheat Sheet
- .NET Security Cheat Sheet
- OWASP Top Ten Cheat Sheet
- Password Storage Cheat Sheet
- Pinning Cheat Sheet
- Query Parameterization Cheat Sheet
- Ruby on Rails Cheatsheet
- REST Security Cheat Sheet
- Session Management Cheat Sheet
- SAML Security Cheat Sheet
- SQL Injection Prevention Cheat Sheet
- Transaction Authorization Cheat Sheet
- Transport Layer Protection Cheat Sheet
- Unvalidated Redirects and Forwards Cheat Sheet
- User Privacy Protection Cheat Sheet
- Web Service Security Cheat Sheet
- XSS (Cross Site Scripting) Prevention Cheat Sheet
Assessment Cheat Sheets (Breaker)
- Attack Surface Analysis Cheat Sheet
- XSS Filter Evasion Cheat Sheet
- REST Assessment Cheat Sheet
- Web Application Security Testing Cheat Sheet
Mobile Cheat Sheets
OpSec Cheat Sheets (Defender)
Draft Cheat Sheets
- Access Control Cheat Sheet
- Application Security Architecture Cheat Sheet
- Business Logic Security Cheat Sheet
- PHP Security Cheat Sheet
- Secure Coding Cheat Sheet
- Secure SDLC Cheat Sheet
- Threat Modeling Cheat Sheet
- Grails Secure Code Review Cheat Sheet
- IOS Application Security Testing Cheat Sheet
- Key Management Cheat Sheet
- Insecure Direct Object Reference Prevention Cheat Sheet
- Content Security Policy Cheat Sheet