web-dev-qa-db-ja.com

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

開発者コンソールにたくさんのエラーが表示されます。

文字列の評価を拒否しました

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

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

スタイルシートのロードを拒否しました

これはどういうことですか。コンテンツセキュリティポリシーはどのように機能しますか? Content-Security-Policy HTTPヘッダーはどうやって使うのですか?

具体的には...

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

そして最後に:

  1. 'self'とはどういう意味ですか?
189
Schlaus

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

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

簡潔にするために、各サンプルで完全なタグを記述することはしません。代わりに、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'のようなspecial以外のパラメーターは引用符で囲まないことに注意してください。また、ディレクティブの後にコロン(:)はありません。ディレクティブのみ、次にスペースで区切られたパラメーターのリスト。

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

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-srcは、XMLHttpRequest(AJAX)、WebSockets、またはEventSourceに対する有効なターゲットを定義します。ここで許可されていないホストに接続しようとすると、ブラウザは400エラーをエミュレートします

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

。複数のディレクティブの使用方法]

セミコロン(;)で終了することにより、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。異なるプロトコルの処理方法]

デフォルトでは、標準プロトコルのみが許可されています。たとえば、WebSockets 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 *"を使用して、それで完了できませんか?

いいえ。明らかなセキュリティの脆弱性に加えて、これは期待どおりに機能しないことにもなります。 一部のドキュメント は何でも許可すると主張していますが、それは正しくありません。インライン化またはevalsは許可されません。したがって、実際にサイトをさらに脆弱にするために、これを使用します。

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

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

さらに読む:

http://content-security-policy.com

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

471
Schlaus

Apache2 MOD_HEADERS

Ubuntu/Debianを使用している場合は、Apache 2のmod_headersを有効にすることもできます。Fedoraでは、デフォルトですでに有効になっています。

# 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を持っているなら、あなたもそれらをホワイトリストに加えるべきであることを発見しました。

インラインコードは有害と見なされているので、避けるべきです。すべてのjavascriptとcssを別々のファイルにコピーしてホワイトリストに追加します。

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

続きを読む:

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

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

12
Erik Hendriks