web-dev-qa-db-ja.com

Access-Control-Allow-Origin:*を返すと、JSON GET応答のセキュリティが低下しますか?

W3C CORSの推奨事項 は次のように述べています。

特定のタイプのリソースは、特定の許可されたオリジンを指定しようとするのではなく、すべてのオリジンを拒否または許可する必要があります。

...

3.エンティティボディがECMAScriptとしてたまたま解析するGET応答は、HTMLスクリプト要素を使用してクロスオリジンにアクセスできるため、機密コメントがない場合、値が「*」のAccess-Control-Allow-Originヘッダーを返すことができます。必要に応じて、このようなリソースは、上記のようにアクセス制御とCSRF保護を実装できます。

JSONはECMAScriptとして解析されますか?

JSONは、HTMLスクリプト要素を介して実行されたときに副作用を生成できますか?

クロスオリジンのWebコンテンツは、HTMLスクリプト要素を介して偽造されたCSRFリクエストからのJSON GETレスポンスへの読み取りアクセスを取得できますか?

この文脈で「デリケートなコメント」とはどういう意味ですか?

この段落は、承認のためにCookieまたはHTTP認証を受け入れないGETリクエストに適用されますか?たとえば、OAuthによってのみリクエストが承認された場合、その応答にはHTMLスクリプト要素を介してブラウザからアクセスできなくなります。しかし、承認されたすべての応答に_Access-Control-Allow-Origin: *_を含めることにより、リクエストがあると、サーバーはブラウザがアクセスを許可するオリジンを指定できなくなります。

_Access-Control-Allow-Origin: *_を含めると、CookieまたはHTTP認証によって承認されたリクエストへの応答のセキュリティが低下しませんか?たとえば、リクエストがCookieによって承認された場合、ブラウザで実行できますが、レスポンス本文のソースコードにはクロスオリジンのウェブコンテンツからアクセスできません。その応答に_Access-Control-Allow-Origin: *_を含めることにより、サーバーはブラウザーに通信し、すべてのオリジンのWebコンテンツが実行に加えて応答を読み取るためのアクセス権を持つ必要があることを示します。

6
Matt McClure

これまでに理解したこと:ここでの主な考え方は、スクリプト要素(<script src="http://example.com/myscript.js">)は同一起源の制限を受けないということです。したがって、サイトは任意のスクリプトURLをロードし、そのスクリプトをexecuteできます(スクリプトが資格情報を必要としないか、ブラウザがスクリプトにアクセスするために必要な資格情報を持っている限り)。ただし、ブラウザは<script>要素にロードされたスクリプトをreadできません。

W3Cの推奨を次のように言い換えることができます:

リソース内のすべての情報をスクリプトとして実行して取得できる場合は、Access-Control-Allow-Origin: *を自由に追加できます。

したがって、未加工のJSONはこの要件を満たしていません。スクリプトを実行する場合:

(["foo", 5, 7])

その後、実行環境に情報は追加されません。 (数年前は Arrayコンストラクターを再定義することにより を使用していた可能性がありますが、最新のブラウザーはこの脆弱性を排除しています。)

ただし、スクリプト

window.secrets = ["foo", 5, 7];

does実行環境に観察可能な変更を加えます。 <script>要素でスクリプトを実行してもページが学習できなかった情報が含まれていないため、Ajaxを介して任意のページにリソースのコンテンツをフェッチすることもできます。

「機密コメント」というフレーズは、実際のJavaScriptコードコメント(/* e.g., like this */)を指します。コメントは<script>の実行からは読み取ることができませんが、Ajaxを介してスクリプトコンテンツにアクセスすると読み取ることができます。たとえば、スクリプト:

// by the way, the fourth secret is "bar"
window.secrets = ["foo", 5, 7]

<script>タグで実行すると、前の例と同じ情報がリークされます。コメントは実際のスクリプトテキストを表示しているときにのみ表示されるためです。

リソースがOAuth資格情報を必要とし、Cookie資格情報を受け入れない場合、 セクション4 は以下を示します:

リクエストはクレデンシャルフラグを設定する必要があり、リソースはリクエストのコンテンツで明示的に提供されるセキュリティトークンを使用して認証を実行する必要があります

HTMLスクリプト要素を介したクロスオリジンリクエストにはOAuth資格情報が含まれることはなく、これらのリクエストはレスポンスのAccess-Control-Allow-Originヘッダーの値に関係なく認証に失敗します。

リソースが認証情報とプリフライトを必要とする場合、プリフライトレスポンスもAccess-Control-Allow-Credentials: trueで提供する必要があります。サーバーがそのヘッダーを送信しない場合、サイトはクロスドメインの認証されたリクエストを送信してスクリプトの内容を読み取ることができません。したがって、サーバーがAccess-Control-Allow-Origin: *も設定しない限り、ターゲットドメインの資格情報はAjax経由で送信されないため、Access-Control-Allow-Credentials: trueは資格情報で保護されたリソースのセキュリティを弱めません。

リソースが認証情報を必要とするがプリフライトは必要ない場合、サーバーがレスポンスにAccess-Control-Allow-Credentials: trueを含める機会がある前に、認証情報がリクエストで送信されます。最終結果は同じです-ブラウザーは要求を行っているクロスオリジンのWebコンテンツと応答を​​共有しません-理由は異なります。

セクション6.1 は言う:

文字列「*」は、資格情報をサポートするリソースには使用できません。

また、リソース共有チェックは セクション7.2 のステップ2を通過し、ステップ3で失敗します。

  1. Access-Control-Allow-Originヘッダー値が「*」文字であり、信任状除外フラグが設定されている場合は、パスを返し、このアルゴリズムを終了します。
  2. Access-Control-Allow-Originの値が、その仕様で定義されているOriginヘッダーの値と大文字小文字を区別しない場合は、失敗して戻り、このアルゴリズムを終了します。
2
apsillers