Content Security Policy 1.0 を Firefox に導入

原文: Content Security Policy 1.0 Lands In Firefox on June 11, 2013 by imelven

Content Security Policy (よく CSP と略されます) は、ページ内にコンテンツを含めることが可能なサイトを制限する、Web ページ向けの手段です。また、インラインスクリプトの実行を許可するかや、インラインのスタイル/CSS をページに適用することを許可するかの制限もできます。一般的に、CSP は Web 開発者に対してコンテンツの強力な制御を可能にして、さまざまなセキュリティ問題の軽減を助けます。CSP の主な利点の一つは、デフォルトでインラインスクリプトを実行させないことです。これは、XSS (クロスサイトスクリプティング) や他のスクリプトインジェクションの脅威を大幅に軽減する助けになります。CSP のすばらしい紹介として、Mike West の投稿 “An Introduction to Content Security Policy” をご覧ください。

ドキュメントでコンテンツ制限を指定できるというアイデアは、少なくとも 2007 年にさかのぼります。当時このアイデアは Mozilla Project の Gervase Markham とセキュリティ研究者の Robert ‘rsnake’ Hansen によって議論されました。Brandon Sterne と Sid Stamm は公式な仕様が存在するよりはるか前に、Firefox 向けに CSP の初期プロトタイプの実装作業を行いました。CSP の ‘前仕様 (pre-spec)’ 実装は 2011 年 3 月に Firefox 4.0 へ投入して、X-Content-Security-Policy ヘッダを使用しました。 CSP のコンセプトはかなり急速に牽引力を得て、Chrome は 2011 年 8 月に X-Webkit-CSP ヘッダを使用して最初の実装を公開しました。セキュリティや Web の専門家による多くの議論を経て、2011 年 11 月に Content Security Policy 1.0 の W3C 仕様のワーキングドラフトが公開されました。時間をかけてコンセプトが発展や改良したことにより、ワーキングドラフトで示された構文は、初期の Firefox 実装で使用されるものとはかなり異なっていました。1 年後に CSP 1.0 仕様が勧告候補に達して、実装する準備が整いました。Chrome は 2 月公開の Chrome 25 で、接頭辞なしのヘッダを使用した CSP 1.0 仕様をサポートしました。Internet Explorer 10 は CSP の ‘sandbox’ ディレクティブをサポートしましたが、現時点で他の CSP ディレクティブは未サポートです。

当初の Firefox CSP 実装と CSP 1.0 仕様とで何が変わりましたか?

  1. ヘッダの接頭辞を削除
    仕様では、X-Content-Security-Policy ではなく Content-Security-Policy ヘッダを定義しています。CSP をサポートするブラウザに適用するポリシーを持つために、サイトが複数の CSP ヘッダを (異なる構文で!) 送信しなければならない状況がなくなるので、よいことです。同一の Content-Security-Policy ヘッダが Firefox、Chrome、IE 10 (sandbox のみ) および仕様を実装する他のブラウザで動作するでしょう。何らかの理由でサイトが X-Content-Security-Policy ヘッダと Content-Security-Policy ヘッダの両方を送信する場合は接頭辞付きのヘッダが無視されて、接頭辞なしのヘッダから得たポリシーだけが適用されます。
  2. 使用できるディレクティブの変更
    ポリシーで使用できるディレクティブが若干変わりました。当初の Firefox CSP 実装では、未指定のディレクティブ向けに使用されるデフォルトポリシーを指定するために ‘allow’ ディレクティブを使用しました。これは CSP 1.0 で ‘default-src’ ディレクティブに置き換えられました。加えて、当初の Firefox の実装では XMLHttpRequest オブジェクトが接続できる生成元を制限するために、‘xhr-src’ ディレクティブを使用しました。1.0 仕様では、‘xhr-src’ が ‘connect-src’ に置き換えられました。また、XHR に加えて EventSource や WebSocket オブジェクトが接続できる場所も制限します。
  3. デフォルトの動作の変更
    当初の Firefox の Content Security Policy 実装は Fail-Close であり、将来の構文に対して下位互換性がありませんでした。CSP 1.0 では、default-src ディレクティブがないときにすべてのソースを許可するようにフォールバックします。
  4. インラインスクリプトと eval() の使用許可に関する変更
    インラインスクリプトや eval() の使用を許可するようオプトインする方法が変わりました。当初の Firefox の CSP 実装では、これを行うために ‘options’ ディレクティブで値 inline-script および eval-script を使用しました。例えば、当初の CSP ポリシーで “allow ‘self’ ; options inline-script eval-script” は、CSP で保護されたドキュメントと同じ生成元からのコンテンツ読み込みと、インラインスクリプト実行および eval() の使用を許可します。
    CSP 1.0 では、この状況を制御するために ‘script-src’ ディレクティブにキーワードが追加されました。‘script-src: unsafe-inline’ がインラインスクリプト許可のオプトイン、‘unsafe-eval’ が eval() の使用許可のオプトインです。CSP を使用する価値を少し落としますが、両方にオプトインするために、両方のキーワードを指定することができます! 例えば CSP 1.0 ポリシーで ‘default-src ‘self’ ; script-src ‘unsafe-inline’ ‘unsafe-eval’ は、CSP で保護されたドキュメントと同じ生成元からのコンテンツ読み込みと、インラインスクリプト実行および eval() の使用を許可します。
  5. インラインスタイルのブロック
    当初の Firefox の CSP 実装では、インラインスタイルをまったくブロックしませんでした。これは CSP 仕様に後で追加されたもので、<style> 要素や他の style 属性を持つ要素を注入することによる攻撃を防ごうとするものです。それらの攻撃は、スクリプトの実行を許可していない場合でも実施できます。ページからデータを取り出すために CSS セレクタを使用して、要素を別の要素の前面に重ねるために属性を使用するといった一部の潜在的な攻撃が、フィッシング攻撃を可能にします。

Firefox の CSP 1.0 実装と仕様との間にまだ相違点はありますか?

はい、小さな違いがいくらかあります。

  • frame-ancestors ディレクティブをまだサポートしています。このディレクティブは X-Frame-Options ヘッダに似ており、どのサイトが Web ページをフレーム化できるかを制限します。X-Frame-Options は非推奨になり、また当初明示された問題点をいくつか抱えています。frame-options ディレクティブによって、この機能を CSP に移すことが提案されました。frame-options は策定中の “User Interface Security Directives for Content Security Policy” 仕様の一部として提案された、新しい CSP ディレクティブです。将来、Firefox の frame-ancestors ディレクティブは、frame-options が選ばれることにより非推奨になるでしょう。
  • report-uri ディレクティブは、CSP 違反のレポートをどこへ送信するかを指定するポリシーを可能にするものです。Firefox ではこれが、CSP が指定されたドキュメントの生成元へのレポート送信に制限されています。レポートを取り巻く適切な制限や懸念に関する議論が、W3C の WebAppSec ワーキンググループや Mozilla で行われています。Bug 843311 をご覧ください。
  • インラインスタイルがブロックされるとき、SMIL アニメーション要素もブロックされます。これの最大の原動力は Bug 704482 です。Mario Heiderich が報告した、スクリプトの実行を許可しない場合でもキーストロークを読み取れる高度な攻撃です。ここで私たちは慎重に取り組み、またこれを W3C の WebAppSec ワーキンググループに持ち込む予定です。
  • Firefox は ‘sandbox’ ディレクティブをサポートしていません。このディレクティブは CSP 1.0 のオプションですが、CSP 1.1 の一部には含められる予定です。

Firefox の CSP は将来どうなりますか?

ある時点で、X-Content-Security-Policy ヘッダを非推奨にする予定です。本投稿の動機のひとつが、接頭辞のない Content-Security-Policy ヘッダを使うようにサイトを移行するときであることを、人々にわかってもらうことです。Firefox は Web コンソールに、接頭辞付きのヘッダは将来非推奨になることを知らせるメッセージを表示します。

加えて、私たちは W3C の WebAppSec で CSP 1.1 仕様の策定に関わっており、Mozilla の Dan Veditz が本仕様のエディターの一人になっています。私たちは特に、script-src および style-src ディレクティブ向けの新たな nonce-source ソースに興奮しています。このソースはポリシーで指定されたものと同じ正当な nonce を提示する場合に、特定のインラインスクリプトやスタイルのホワイトリスト化を可能にします。nonce-source は最近 Blink に実装され、また Firefox では開発中です。詳しくは CSP 1.1 仕様のセクション 4.10.1 “Usage” をご覧ください。なお、この仕様は現在急速に発展中であることにご注意ください!

Mozilla にて私たちは、CSP のインラインスタイルのブロックについてさらに議論しました。特に、eval() のブロックと似た機能を追加したいという希望があります。その根拠は、文字列からスタイルを構築することも本質的に危険であるためです。これは Bug 873302 で扱っており、また一部の議論は、元の ‘インラインスタイルのブロック’ バグ側にあります。私たちはごく近い将来にこのアイデアを、より多くのフィードバックを得るために W3C の WebAppSec ワーキンググループに持ち込む予定です。Mozilla 内では、.innerHTML の使用をブロックする CSP ディレクティブの作成も提案されました (また、ワーキンググループ内でも多少議論しました)。.innerHTML による script 要素の挿入がインラインスクリプトをブロックする CSP でブロックされるとしても、.innerHTML 内の信頼されない入力を使用することで他にもさまざまな問題が生じる可能性があります。

ここまでは長すぎました。現在 Content-Security-Policy ヘッダをどれで使用できるかだけを教えてもらえますか?

  • Firefox : 現在はデスクトップ版の Firefox 23 (Aurora) およびそれ以降です。Android 版 Firefox と Firefox OS がすぐ後に続きます。
  • Chrome : 25 およびそれ以降
  • Internet Explorer : 10 およびそれ以降 (sandbox ディレクティブのみ)

謝辞

  • Mozilla で始めに CSP の開発を先導しました: Brandon Sterne
  • Mozilla の Security Engineering & Security Assurance、特に Sid Stamm、Brian Smith、Daniel Veditz、Garrett Robinson、Mark Goodwin、Frederick Braun、Tanvi Vyas
  • CSP に熱中した仲間たち: Mike West、Adam Barth、Brad Hill、Devdatta Akhawe、Neil Matatall、Joel Weinberger、Kailas Patel