はじめに
CORS(Cross-Origin Resource Sharing)について調べたとき、「結局CORSって何?」となり理解に時間がかかったのでなるべく簡潔にまとめてみた。
対象読者
CORSをはじめて聞く人向けにざっくり解説する😊
結論
とりあえず結論を書くが、恐らくこれだけだとイメージしづらい…💦
✅CORSとは、別のオリジン(≒別ドメイン)のリソース(≒データ)に安全にアクセスできる仕組み。
✅CORSは、同一オリジンポリシーの不便さを解消してくれる。
✅CORSがないと別オリジンのAPIからデータを取ってくることもできない。
【問題点】同一オリジンポリシー
CORSを理解するためにまずは「同一オリジンポリシー」について簡単に解説する。
同一オリジンポリシーとは
✅「別のオリジン(≒別ドメイン)のリソース(≒データ)にはアクセス不可にしよう!」という安全性を重視したポリシー。
✅つまりよそのサイトからデータが取れないように制限がかかるイメージ!
Chromeなどのブラウザがこのポリシーに則っている。
【補足】オリジンとは
✅スキーム+ホスト+ポートのこと。
https://example.com:80
などがオリジン!ちなみにドメインはexample.comのことなので異なるものだが、ざっくり話を理解する上では「別のオリジン ≒ 別ドメイン」くらいでOK。
何の役に立つ?
✅攻撃を防ぐためにある。
攻撃例
以下のような攻撃を防いでいる。
- クロスサイトスクリプティング(XSS)
- クロスサイトリクエストフォージェリ(CSRF)
- クロスオリジンデータ漏洩(*1)
(*1)クロスオリジンデータ漏洩のイメージ
以下のような流れでデータが漏洩する。
sequenceDiagram participant User as ユーザー participant AttackerWebsite as 😈攻撃者のウェブサイト participant TargetWebsite as ターゲットウェブサイト User->>AttackerWebsite: ①攻撃者のウェブサイト訪問 AttackerWebsite->>User: ②悪意のあるスクリプトをレスポンス User->>TargetWebsite: ③他のウェブサイトへリクエスト TargetWebsite->>User: ④レスポンス(プライバシー関連データ含む) User->>AttackerWebsite: ⑤データ漏洩
- 攻撃者のウェブサイト訪問
ユーザーが攻撃者のウェブサイトを訪れる。
- 攻撃者のウェブサイトからのレスポンス
悪意のあるスクリプトがユーザーに返ってくる。
- 他のウェブサイトへリクエスト
悪意のあるスクリプトが実行される。
ユーザーのブラウザを介して他のウェブサイト(攻撃したいサイト)にリクエストを送信する。
※ユーザー情報を取得するリクエストが実行されることが多い。ユーザーがサイトにログイン済みだと特に危険。
- 他のウェブサイトからレスポンスが返ってくる
レスポンスには、ユーザーのプライバシーに関連するデータや情報が含まれる可能性がある。
- 攻撃者のウェブサイトへのデータ漏洩
悪意のあるスクリプトによって、得たデータを攻撃者のウェブサイトに送信してしまう。
つまり攻撃者はユーザーのブラウザを介してターゲットサイトのデータや情報が取得できる。
同一オリジンポリシーは安全だけど不便
別サイトからAPIでデータを取ってくることもできない!不便💦
※JSONPを使って同一オリジンポリシーに引っかからずに別サイトからデータを取る方法もあるが、安全面には課題がある。
【解決策】CORS
同一オリジンポリシーの問題点(不便さ)を理解したところで、CORSについて見てみる。
CORSとは
✅別のオリジン(≒別ドメイン)とリソース(≒データ)を安全に共有する仕組み。
↑さっきの同一オリジンポリシーではNGだった行為が可能に!
※CORSを日本語に訳すと「オリジン間リソース共有」
同一オリジンポリシー と CORS
同一オリジンポリシーでは「別ドメインからデータを取れない安全な仕組みを作った!」って言っていたのに、CORSは「別ドメインからデータを取れる仕組みだよ!」と正反対のことを言っている🤔
この2つを整理すると…
これがCORSのざっくりとしたイメージ😊
ざっくりと知りたいだけの方はここまで理解すれば十分⭕️
技術的なお話(読み飛ばしてOK)
許可されたサイトの場合はレスポンスが受け取れる
✅事前に「example.comさんはデータを持っていっていいよ〜☺️」みたいに決めておくことで、リソース共有できるようになる。
データが共有されるまでの流れ
sequenceDiagram participant User as ユーザー participant ClientWebsite as example.com participant ServerWebsite as APIサーバーなど User->>ClientWebsite: ①サイト訪問 ClientWebsite->>User: ②正常なスクリプトをレスポンス User->>ServerWebsite: ③CORSリクエスト送信 ServerWebsite->>User: ④CORSヘッダで許可されたレスポンス User->>ClientWebsite: ⑤安全にデータ共有
- 「③CORSリクエスト送信」でどのサイトからのリクエストか?を知らせている。
具体的にはリクエストヘッダーの「Originヘッダー」もしくは 「Access-Control-Request-〇〇ヘッダー」にその情報が格納されている。
- 「④CORSヘッダで許可されたレスポンス」で事前に許可されたサイトからのリクエストだったか?を返している。
具体的にはレスポンスヘッダーの「Access-Control-Allow-〇〇」にその情報が格納されている。
許可がない場合はリクエストが受け取れない
✅事前に許可していないオリジン(≒別ドメイン)からリクエストがあった場合はレスポンスが受け取れない仕組み。
その結果JavaScriptがレスポンスにアクセスできずセキュリティが保たれる。
sequenceDiagram participant UserBrowser as ユーザーのブラウザ participant ClientWebsite as 😈hoge.com participant ServerWebsite as APIサーバーなど UserBrowser->>ClientWebsite: ①サイト訪問 ClientWebsite->>UserBrowser: ②正常なスクリプトをレスポンス UserBrowser->>ServerWebsite: ③リクエスト送信 ServerWebsite->>UserBrowser: ④レスポンス(アクセス未許可) UserBrowser->>UserBrowser: ⑤レスポンスを遮断(JavaScriptからアクセス不可)
- 「④レスポンス(アクセス未許可)」では、許可/未許可に関わらずデータを返す。
- 「⑤レスポンスを遮断(JavaScriptからアクセス不可)」のタイミングで、取得したデータにアクセスできないようにブラウザが遮断してくれる。