HTTPに関するセキュリティリスクについて(その5)
CORS(Cross-Origin Resource Sharing)について
CORSの仕組みもHTTPメッセージヘッダを利用して実現されます。
本来、異なるオリジン(Cross-Origin)のリソースをJavaScriptから読み込んだりCanvas上に表示したりすることはSame-Origin Policy(同一生成元ポリシー)によってブロックされます。
例えば、JavaScriptでXMLHttpRequestを使った異なるオリジンへのリクエストや、<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では制限されないので表示されます。
例えば、AWS(Amazon Web Services)のS3にWebアプリケーションで使用される画像データをデプロイして<img>タグで表示させるだけであれば開発者は何もする必要はありません。
しかし、その<img>タグで読み込まれた画像をCanvasで表示するためにスクリプトの中で読み込もうとするとSame-Origin
Policyの制限でブロックされることになります。
現在の主要なブラウザはCORSに対応しているため、スクリプトから異なるオリジンへのリクエスト時にはHTTPメッセージへ自動的にCORS確認用のヘッダが追加されます。
(今回は「単純リクエスト」の例になります。「単純リクエスト」の条件を満たさないケースでは「プリフライトリクエスト」の手順でやり取りされます)
AWSのS3はリクエストにOriginヘッダが含まれている場合はデフォルトで「Access-Control-Allow-Origin:
*」を返しています。リソースを利用できるオリジンの範囲を制限したいときは個別のオリジンを指定します。
ここでCDNを使ったリソースの利用を考えていきます。
AWSのS3をCDNのオリジンサーバーとして配置し、AWSのCDNサービスである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側にS3へOriginを送る設定を追加する必要があります)
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の仕様を正しく理解した上で適切な設定を行えば安全な通信が確立できます。
その他、情報セキュリティに関する記事リンク
国家資格になった情報処理安全確保支援士を会社に所属させるメリットについて考える
情報処理技術者試験の勉強まとめ記事一覧はこちら↓
【情報処理技術者試験に役立つ!】用語と解説をまとめたリンク集(PDFデータ付き)
0 件のコメント:
コメントを投稿