開発者コンソールにたくさんのエラーが表示されます:
文字列の評価を拒否しました
次のコンテンツ セキュリティ ポリシー ディレクティブに違反しているため、インライン スクリプトの実行を拒否しました
スクリプトの読み込みを拒否しました
スタイルシートの読み込みを拒否しました
これって一体何ですか? コンテンツ セキュリティ ポリシー (CSP) はどのように機能しますか? Content-Security-Policy
HTTP ヘッダーはどのように使用すればよいですか?
具体的には、どのようにすれば...
- ...複数のソースを許可しますか?
- ...異なるディレクティブを使用しますか?
- ...複数のディレクティブを使用しますか?
- ...ポートを処理しますか?
- ...異なるプロトコルを処理しますか?
- ...
file://
プロトコルを許可しますか? - ...インライン スタイル、スクリプト、タグを使用します
<style>
か<script>
? - ...許可する
eval()
?
そして最後に:
- 正確にはどういう
'self'
意味ですか?
ベストアンサー1
メタタグContent-Security-Policy
を使用すると、クロススレッドリソースを読み込む場所を定義できるようにすることで、ブラウザが他の場所からデータを読み込むのを防ぎ、攻撃を阻止します。これにより、攻撃者がサイトに悪意のあるコードを挿入することが難しくなります。
なぜ CSP エラーが次々に発生するのか理解しようとして頭を悩ませましたが、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-src
XMLHttpRequest (AJAX)、WebSocket、または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 は悪であり、差し迫った世界の終末の原因となる可能性が高いので、そうではないと言うでしょう。そのような人は間違っています。確かに、eval を使用するとサイトのセキュリティに大きな穴を開けることができますが、eval には完全に有効な使用例があります。eval を賢く使用する必要があります。次のように許可します。
content="script-src 'unsafe-eval'"
9. 正確にはどういう'self'
意味ですか?
ローカルホスト、ローカルファイルシステム、または同じホスト上の何かを意味すると解釈されるかもしれません'self'
。これらのいずれを意味するわけでもありません。コンテンツ ポリシーが定義されているファイルと同じスキーム (プロトコル)、同じホスト、同じポートを持つソースを意味します。サイトを HTTP 経由で提供していますか? 明示的に定義しない限り、https は使用できません。
通常は含めるのが理にかなっているため、ほとんどの例で使用しています'self'
が、必須ではありません。必要がない場合は省略してください。
でもちょっと待ってください!ただ使ってcontent="default-src *"
終わりにできないのですか?
いいえ。明らかなセキュリティ上の脆弱性に加えて、これは期待通りには機能しません。いくつかのドキュメント何でも許可すると主張していますが、それは真実ではありません。インライン化や eval は許可されないので、サイトを本当に脆弱にするには、次のようにします。
content="default-src * 'unsafe-inline' 'unsafe-eval'"
...でも、そうはならないと信じています。
参考文献: