RIT Tech Blog

株式会社RITのエンジニアが知見を共有する技術ブログです。

CORS(Cross-Origin Resource Sharing)とSOP(Same-origin policy)について

こんにちは。エンジニアの岸本です。

個人的な開発をしていて、linkタグで @font-face を使った Web フォントの読み込みをする際に「crossoriginが付与されていませんよ!」警告を頂戴した。何となくで理解していたcrossorigin属性の存在意義を調べるうちにCORS(Cross-Origin Resource Sharing)とSOP(Same-origin policy)について改めて学習する機会になったのでまとめてみることしました。

「crossorigin」とは一体なに?

「CORS(Cross-Origin Resource Sharing)設定要素として定義されており、CORSの振る舞いに関する設定ができる」

「crossorigin」の存在意義はズバリ!

「セキュリティリスクを減らしてくれる凄いやつ」 CORSを利用することでセキュリティリスクを回避できることは解ったが、 実際にどのような機能なのか釈然としなかったのでCORSについておさらいします。

CORS(Cross-Origin Resource Sharing)とは?

別オリジンのリソースへアクセス(HTTPリクエスト)できるようにするために、SOP(Same-origin policy)の機能をカバーする形で誕生した仕組み

簡単な具体例

CORSが生まれた背景

CORSとは異なるオリジンへのアクセスを許可する方法です。それだけを聞いても何がすごいのか解らないですよね。 CORSもSOPも存在しない仮想ケースで考えてみます。 img_2 上記のように、なりすましメールや悪意あるサイトをクリックしてしまうことで スクリプトがダウンロードされ、攻撃対象へリクエストが送信されてしまう可能性があります。 そこで生まれたのがSOP(Same-origin policy)です。 同じオリジンじゃなければ不正とみなすことで上記リクエストによる被害防止につながります。(実際にアクセス自体は可能だがレスポンスの取得が制限される) img_1

しかし別の問題が発生しました。 Ajaxの普及・発展によって異なるオリジン(ほとんどの場合、異なるホスト)のAPIを利用したいという動機が生まれたので SOPだけでは役割を満たすためには不十分になってしまいました。(厳密にはJSONPという裏技レベルの解決策もあったが安全性的に十分ではなかった模様)そこで活躍するのがCORS(Cross-Origin Resource Sharing)です。 HTTPヘッダを用いたアクセス制御のコントロールを行うことで、SOPでは満たせなかった柔軟性をカバーすることが可能になりました。

というのが、ざっくりとしたCORSとSOPの説明になります。 linkタグ等々に付与しているcrossorigin属性に話を戻します。

結論から言うと、以下のケースはSOPが適用されないため、「異なるオリジンへアクセスできるようにCORSを考慮する必要が基本的にはない」ということになります。

developer.mozilla.org

  • imgタグのsrc属性で読み込んだ画像
  • linkタグのhref属性で読み込んだ CSS
  • scriptタグのsrc属性で読み込んだ JavaScript
  • video, audioタグのsrc属性で読み込んだマルチメディアファイル
  • iframe, frameタグのsrc属性での別サイトコンテンツの読み込み
  • @font-face が適用されたフォント ※ X-Frame-Options の設定によっては読み込みがブロックされます

自分のケースではMDNにも記載があるように、「異なるオリジンのフォントを許容するブラウザもありますが、同一オリジンを要求するものもある 」ことを想定してcrossoriginを付与するように警告を頂戴したようです。

おまけ

「scriptタグのsrc属性で読み込んだ JavaScript」にはSOPが適用されないと言っても実際にはcrossorigin属性を付与されているscriptタグやimgタグを見ることはありますよね。個人的には以下のようなケースが想定されるからと理解しています。

「crossorigin属性をつけない限りSOP/CORSの制約は発生しない。つまり、CORSを経由せずに取得された場合は汚染フラグ (taint flag) が立てられ、スクリプトから利用したときに一定の制限が課される(<script> が例外を発生させたときに window.onerror が受け取るエラー情報が制限される等)からcrossorigin属性を付与っている方がベター」