【情報処理安全確保支援士】HTTPに関するセキュリティリスクについて(その5): CORS(Cross-Origin Resource Sharing)について

2021年11月29日月曜日

HTTP セキュリティ 情報処理安全確保支援士

t f B! P L


 HTTPに関するセキュリティリスクについて(その5)



前回の記事「Cookieに対するセキュリティについて」



CORS(Cross-Origin Resource Sharing)について


CORSの仕組みもHTTPメッセージヘッダを利用して実現されます。

本来、異なるオリジン(Cross-Origin)のリソースをJavaScriptから読み込んだりCanvas上に表示したりすることはSame-Origin Policy(同一生成元ポリシー)によってブロックされます。

例えば、JavaScriptXMLHttpRequestを使った異なるオリジンへのリクエストや、<img>タグで読み込んだ異なるオリジンに存在する画像をCanvasに表示する場合などは同一生成元ポリシーの制約によりブロックされ利用できません。


しかし、この制約があることによって悪意のある第三者が作成したスクリプトから正規のページのリソースや情報にアクセスされることを防ぐことができます。

 

例えば制約が無かったとすると、悪意のある第三者が用意したiframeをもつHTMLページのiframeの中に利用者が遷移したい本来のページを表示させた場合、そこでパスワードなどの秘匿情報を利用者が入力してしまうとその情報をiframe側(攻撃者側)のスクリプトによって盗まれてしまいます

(実際にはSame-Origin Policyにより防止されます)

 

Same-Origin Policyの制限が無ければXSS攻撃に対してノーガード状態となってしまいます。

(実際のXSS攻撃はSame-Origin Policyを巧みに回避して同一オリジンとなるようにスクリプトを送り込みます)

 

同一生成元ポリシーの制限があることによって特定の状況のセキュリティは高まりますが、その反面、外部にリソースを公開したいWebサービスや、静的リソースを外部サーバに配置してデプロイをしたいケースなどが実現できなくなります。

(プロキシサーバやJSONPなどで回避することはできます)

 

そのためにSame-Origin Policyの制約の一部を解除して異なるオリジンに存在するリソースの使用を安全に許可する仕組みCORSになります。



CORSを設定しなくてもSame-Origin Policyの影響を受けないケース




異なるオリジンに配置された画像のURLを自分のサイトのHTMLページで<img>タグのsrc属性に指定してもSame-Origin Policyでは制限されないので表示されます。

例えば、AWSAmazon Web Services)のS3Webアプリケーションで使用される画像データをデプロイして<img>タグで表示させるだけであれば開発者は何もする必要はありません。

 

しかし、その<img>タグで読み込まれた画像をCanvasで表示するためにスクリプトの中で読み込もうとするとSame-Origin Policyの制限でブロックされることになります。

 

現在の主要なブラウザはCORSに対応しているため、スクリプトから異なるオリジンへのリクエスト時にはHTTPメッセージへ自動的にCORS確認用のヘッダが追加されます。

 

(今回は「単純リクエスト」の例になります。「単純リクエスト」の条件を満たさないケースでは「プリフライトリクエスト」の手順でやり取りされます)



「単純リクエスト」時に追加されるヘッダ



このリクエストに対して、サーバ側は次のヘッダを返す必要があります。




AWSS3はリクエストにOriginヘッダが含まれている場合はデフォルトで「Access-Control-Allow-Origin: *」を返しています。リソースを利用できるオリジンの範囲を制限したいときは個別のオリジンを指定します。

 

ここでCDNを使ったリソースの利用を考えていきます。

AWSS3CDNのオリジンサーバーとして配置し、AWSCDNサービスであるCloudFrontでコンテンツを配布することにします。

HTMLページの<img>タグのsrc属性には「S3のオリジン」でURLを指定しますが、「S3のオリジン」に対するDNSの名前解決ではAレコードにはS3のオリジンCNAMEレコードには「CloudFrontのオリジン」が指定されているため、実際にデータをダウンロードするのはCloudFrontが用意しているエッジロケーションサーバのどれかからになります。CloudFrontにキャッシュするための最初のリクエストでCloudFrontからS3へリクエストした際、S3から返される「Access-Control-Allow-Origin」の値も含めてレスポンス内容がCloudFrontにキャッシュされるため、CORSによりSame-Origin Policyでブロックされることがありません。

(場合によってはCloudFront側にS3Originを送る設定を追加する必要があります)

 

CORSを利用することによって外部リソースを安全に共有することができますが、開発者の設定ミスにより脆弱性が生まれてしまうことがあります。



例えば、資格情報Cookie、認証ヘッダー、TLSクライアント証明書)を含むレスポンスを外部オリジンに共有するには、CORSリクエスト時にブラウザ側で資格情報が含まれることを承認し(XMLHttpRequest.withCredentials=trueなど)、かつサーバ側のレスポンスヘッダ―でAccess-Control-Allow-Credentials: true」を返す必要があります。

 

開発者がSame-Origin Policyを回避するために、常にレスポンスヘッダーへ

Access-Control-Allow-Origin: [リクエストしたOrigin]

Access-Control-Allow-Credentials: trueを含めて返してしまっている場合は、悪意のある第三者の作成したスクリプトを利用者が実行することによって資格情報が外部に流出する可能性があります。

 

脆弱性を生む間違ったレスポンス




Same-Origin Policyの制限によってエラーが出た場合は、CORSの仕様を正しく理解した上で適切な設定を行えば安全な通信が確立できます


手間をおしまず一つ一つ丁寧に対応していきましょう。


次回:「HTTPのバージョンについて」




このブログを検索

ブログをよくする

自己紹介

自分の写真
はじめまして。あまるちゃんです。 子供のプログラミング学習に協力できるように教え方を勉強中です。 このブログでは自分が学んだことを投稿していきます。

連絡フォーム

名前

メール *

メッセージ *

ブログ アーカイブ

QooQ