コンテンツセキュリティポリシーはどのように機能しますか?


248

開発者コンソールにたくさんのエラーが出ます:

文字列の評価を拒否

次のコンテンツセキュリティポリシーディレクティブに違反しているため、インラインスクリプトの実行を拒否されました

スクリプトの読み込みを拒否

スタイルシートの読み込みを拒否しました

これは一体何なのでしょう?コンテンツセキュリティポリシーはどのように機能しますか?Content-Security-PolicyHTTPヘッダーを使用するにはどうすればよいですか?

具体的には...

  1. ...複数のソースを許可しますか?
  2. ...別のディレクティブを使用しますか?
  3. ...複数のディレクティブを使用しますか?
  4. ...ポートを処理しますか?
  5. ...異なるプロトコルを処理しますか?
  6. ... file://プロトコルを許可しますか?
  7. ...使用インラインスタイル、スクリプト、およびタグ<style><script>
  8. ...許可するeval()

そして最後に:

  1. 正確には'self'どういう意味ですか?

回答:


557

Content-Security-Policyメタタグは、あなたがのリスク軽減することができますXSSのリソースは、他の場所からのデータのロードからブラウザを防止すること、からロードすることができますどこに定義できるようにすることで、攻撃を。これにより、攻撃者が悪意のあるコードをサイトに挿入することが困難になります。

レンガの壁に頭をぶつけて、なぜCSPエラーが次々と発生するのかを理解しようとしましたが、それがどのように機能するのかについての簡潔で明確な指示はなさそうでした。そこで、CSPのいくつかのポイントを簡単に説明しようとする私の試みは、主に解決するのが難しいと思われることに集中しています。

簡潔にするために、各サンプルでは完全なタグを記述しません。代わりに、contentプロパティのみを表示するので、サンプルcontent="default-src 'self'"はこれを意味します:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

1.複数のソースを許可するには?

ディレクティブの後にスペースで区切られたリストとしてソースをリストするだけです:

content="default-src 'self' https://example.com/js/"

のような特別なもの以外のパラメータは引用符で囲まないことに注意してください'self'。また、:ディレクティブの後にコロン()はありません。ディレクティブのみ、次にスペースで区切られたパラメーターのリスト。

指定されたパラメータ以下はすべて暗黙的に許可されます。つまり、上記の例では、これらは有効なソースになります。

https://example.com/js/file.js
https://example.com/js/subdir/anotherfile.js

ただし、これらは無効です。

http://example.com/js/file.js
^^^^ wrong protocol

https://example.com/file.js
                   ^^ above the specified path

2.異なるディレクティブを使用する方法、それぞれは何をしますか?

最も一般的なディレクティブは次のとおりです。

  • default-src JavaScript、画像、CSS、フォント、AJAXリクエストなどをロードするためのデフォルトポリシー
  • script-src JavaScriptファイルの有効なソースを定義します
  • style-src CSSファイルの有効なソースを定義します
  • img-src 画像の有効なソースを定義します
  • connect-srcXMLHttpRequest(AJAX)、WebSockets、またはEventSourceの有効なターゲットを定義します。ここで許可されていないホストに接続しようとすると、ブラウザは400エラーをエミュレートします

他にもありますが、これらはあなたが必要とする可能性が最も高いものです。

3.複数のディレクティブを使用するには?

セミコロン(;)で終了することにより、すべてのディレクティブを1つのメタタグ内に定義します。

content="default-src 'self' https://example.com/js/; style-src 'self'"

4.ポートの処理方法は?

許可されたドメインの後にポート番号またはアスタリスクを追加して、デフォルトのポート以外のすべてを明示的に許可する必要があります。

content="default-src 'self' https://ajax.googleapis.com http://example.com:123/free/stuff/"

上記の結果:

https://ajax.googleapis.com:123
                           ^^^^ Not ok, wrong port

https://ajax.googleapis.com - OK

http://example.com/free/stuff/file.js
                 ^^ Not ok, only the port 123 is allowed

http://example.com:123/free/stuff/file.js - OK

前述のとおり、アスタリスクを使用してすべてのポートを明示的に許可することもできます。

content="default-src example.com:*"

5.異なるプロトコルをどのように処理しますか?

デフォルトでは、標準プロトコルのみが許可されています。たとえば、WebSocket ws://を許可するには、明示的に許可する必要があります。

content="default-src 'self'; connect-src ws:; style-src 'self'"
                                         ^^^ web sockets are now allowed on all domains and ports

6.ファイルプロトコルを許可するにはfile://

そのように定義しようとすると、機能しません。代わりに、次のfilesystemパラメーターで許可します。

content="default-src filesystem"

7.インラインスクリプトとスタイル定義の使用方法

明示的に許可されていない限り、インラインスタイル定義、<script>タグ内のコード、またはのようなタグプロパティでは使用できませんonclick。あなたはそうすることができます:

content="script-src 'unsafe-inline'; style-src 'unsafe-inline'"

また、base64でエンコードされたインライン画像を明示的に許可する必要もあります。

content="img-src data:"

8.許可するにはeval()

「評価は悪」であり、世界の差し迫った終わりの最も可能性の高い原因であるため、多くの人があなたがそうしないと言うだろうと確信しています。それらの人々は間違っているでしょう。もちろん、evalを使用してサイトのセキュリティに大きな穴をあけることはできますが、完全に有効なユースケースがあります。あなたはそれを使うことについて賢くする必要があります。次のように許可します。

content="script-src 'unsafe-eval'"

9.正確には'self'どういう意味ですか?

'self'ローカルホスト、ローカルファイルシステム、または同じホスト上の何かを意味するかもしれません。それはそれらのいずれかを意味するものではありません。これは、コンテンツポリシーが定義されているファイルと同じスキーム(プロトコル)、同じホスト、同じポートを持つソースを意味します。HTTP経由でサイトを提供しますか?その場合、明示的に定義しない限り、httpsはありません。

'self'ほとんどの例では、通常はそれを含めるのが理にかなっているので使用しましたが、決して必須ではありません。不要な場合は省略してください。

しかし、ちょっと待ってください!私はそれを使用content="default-src *"してそれで終わらせることはできませんか?

いいえ。明らかなセキュリティの脆弱性に加えて、これも期待どおりに機能しません。にもかかわらず、いくつかのドキュメントが主張するそれは真実ではない何かを、ことができます。インライン化や評価は許可されていないため、実際にサイトを非常に脆弱なものにするには、次のようにします。

content="default-src * 'unsafe-inline' 'unsafe-eval'"

...しかし、私はあなたがそうしないと信じています。

参考文献:

http://content-security-policy.com

http://en.wikipedia.org/wiki/Content_Security_Policy


6
素晴らしいポスト。1つのこと:複数のディレクティブが指定されたときに何が起こるかは明らかではありません。例3のstyle-src設定はdefault-srcよりも優先されますか?など...
track0

29
したがって、コンテンツがすべてであることをすべて許可するためにdefault-src *; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'; img-src * data: 'unsafe-inline'; connect-src * 'unsafe-inline'; frame-src *;
アーノルドロア

8
content="default-src * 'unsafe-inline' 'unsafe-eval'"一部のAngularアプリケーションを機能させるためには、それが必要であることを理解することが重要です。
フランジャー001

2
@Maheshその「ブログ」は、SOからコピーされた投稿でいっぱいです。多くのSOユーザーが未知のブロガーからコンテンツをコピーする可能性は低いようです。
シュラウス

2
connect-srcとパスに関する短いメモ:サブパス全体を含める場合は、末尾のスラッシュが必須です。例:ファイルはhttp://foo.com/files/bar.txtソースがある場合はブロックされますhttp://foo.com/filesが、それはだ時に役立ったhttp://foo.com/files/
Griddo

15

APACHE2 MOD_HEADERS

Apache2 mod_headersを有効にすることもできます。Fedoraでは、Ubuntu / Debianを使用している場合は、次のように有効にします。

# First enable headers module for Apache2, 
# then restart the Apache2 service   
a2enmod headers
apache2 -k graceful

Ubuntu / Debianでは、ファイルにヘッダーを設定できます /etc/apache2/conf-enabled/security.conf

#
# Setting this header will prevent MSIE from interpreting files as something
# else than declared by the content type in the HTTP headers.
# Requires mod_headers to be enabled.
# 
#Header set X-Content-Type-Options: "nosniff"

#
# Setting this header will prevent other sites from embedding pages from this
# site as frames. This defends against clickjacking attacks.
# Requires mod_headers to be enabled.
#
Header always set X-Frame-Options: "sameorigin"
Header always set X-Content-Type-Options nosniff
Header always set X-XSS-Protection "1; mode=block"
Header always set X-Permitted-Cross-Domain-Policies "master-only"
Header always set Cache-Control "no-cache, no-store, must-revalidate"
Header always set Pragma "no-cache"
Header always set Expires "-1"
Header always set Content-Security-Policy: "default-src 'none';"
Header always set Content-Security-Policy: "script-src 'self' www.google-analytics.com adserver.example.com www.example.com;"
Header always set Content-Security-Policy: "style-src 'self' www.example.com;"

注:これはファイルの下部です。最後の3つのエントリのみがCSP設定です。

最初のパラメーターはディレクティブ、2番目のパラメーターはホワイトリストに登録されるソースです。Googleアナリティクスと広告サーバーを追加しました。さらに、Apache2で構成されているwww.example.comやexample.comなどのエイリアスがある場合は、それらもホワイトリストに追加する必要があることもわかりました。

インラインコードは有害であると見なされるため、回避する必要があります。すべてのjavascriptsとcssを個別のファイルにコピーし、ホワイトリストに追加します。

あなたがそれにいる間、他のヘッダー設定を見て、mod_securityをインストールすることができます

参考文献:

https://developers.google.com/web/fundamentals/security/csp/

https://www.w3.org/TR/CSP/


2
共有ホストでApache構成を編集する機能がないため、.htaccessファイルに同じディレクティブを追加できました。これらの設定を調整するための優れたツールをreport-uri.io/home/tools見つけました
Michael McGinnis

tomcat 7でこれを解決する方法はありますか?フィルターを追加しようとしましたが、うまくいきませんでした。
Elshan

0

font-srcは他のフォントと同じように機能することを忘れないでください。ただし、他のオリジンからロードされたフォントを使用する場合は、必ずメタタグに追加してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.