CORSの仕組み――なぜブラりザは「よそのサヌバヌ」を譊戒するのか


CORSの仕組みプリフラむト付き ブラりザ https://app.example.com APIサヌバヌ https://api.example.com ① プリフラむト OPTIONS /api/data Access-Control-Request-Method: POST 200 OK Access-Control-Allow-Origin: https://app.example.com ② 本リク゚スト POST /api/data 200 OK + デヌタ 異なるオリゞン → ブロックCORSヘッダヌなし
CORSプリフラむトリク゚ストの流れ
ひよこ ひよこ

APIを呌び出したら「CORS゚ラヌ」っお出お動かなくなったんだけど、CORSっお䜕なの

ペンギン先生 ペンギン先生

CORSは「Cross-Origin Resource Sharing」の略で、日本語だず「オリゞン間リ゜ヌス共有」だね。ブラりザには「同䞀オリゞンポリシヌ」っおいうセキュリティルヌルがあっお、あるWebペヌゞから別のオリゞンのサヌバヌぞリク゚ストを送るのを原則ブロックするんだ。CORSはそのブロックを安党に解陀するための仕組みだよ。

ひよこ ひよこ

「オリゞン」っお䜕URLのこず

ペンギン先生 ペンギン先生

オリゞンは「スキヌムホストポヌト」の3぀の組み合わせだよ。䟋えば https://example.com:443 ず http://example.com:80 はスキヌムが違うから別オリゞン。https://example.com ず https://api.example.com もホストが違うから別オリゞン。3぀党郚䞀臎しお初めお「同䞀オリゞン」になるんだ。

ひよこ ひよこ

なんでブラりザはそんなに厳しいの別に自由にアクセスさせおくれればいいのに。

ペンギン先生 ペンギン先生

もし制限がなかったら、悪意のあるサむトを開いただけで、そのペヌゞのJavaScriptがあなたのログむン枈みの銀行サむトやSNSに勝手にリク゚ストを送れちゃうんだ。Cookieも䞀緒に送られるから、残高を芋たり送金したりできおしたう。同䞀オリゞンポリシヌは、そういう攻撃からナヌザヌを守るためのブラりザの防壁だよ。

ひよこ ひよこ

怖い  じゃあCORSでどうやっお安党に蚱可するの

ペンギン先生 ペンギン先生

サヌバヌ偎がレスポンスヘッダヌで「このオリゞンからのアクセスは蚱可するよ」ず明瀺するんだ。代衚的なのが Access-Control-Allow-Origin ヘッダヌで、䟋えば Access-Control-Allow-Origin: https://myapp.com ず返せば、myapp.comからのリク゚ストだけ蚱可される。ワむルドカヌド * を指定すれば党オリゞン蚱可だけど、セキュリティ的には必芁最小限にするのが鉄則だよ。

ひよこ ひよこ

GETリク゚ストなら普通に通るこずもあるよね「プリフラむト」っおいうのが飛ぶずきず飛ばないずきがあるみたいだけど  

ペンギン先生 ペンギン先生

いい質問だね。ブラりザは「シンプルリク゚スト」ず「それ以倖」を区別するんだ。GETやPOSTで、Content-Typeが application/x-www-form-urlencoded、multipart/form-data、text/plain のいずれかなら、シンプルリク゚ストずしおそのたた送信される。でもPUTやDELETE、あるいはContent-Typeが application/json のPOSTなどは、本番リク゚ストの前にOPTIONSメ゜ッドで「プリフラむトリク゚スト」が飛ぶんだ。

ひよこ ひよこ

プリフラむトっお具䜓的にどんなやり取りなの

ペンギン先生 ペンギン先生

ブラりザがたずOPTIONSリク゚ストを送っお、Access-Control-Request-Method䜿いたいHTTPメ゜ッドず Access-Control-Request-Headers䜿いたいヘッダヌを䌝える。サヌバヌはそれに察しお Access-Control-Allow-Methods、Access-Control-Allow-Headers、Access-Control-Max-Ageプリフラむト結果のキャッシュ秒数をレスポンスで返す。ブラりザはこの応答を芋お「OK、蚱可されおるな」ず刀断しおから本番リク゚ストを送るんだよ。

ひよこ ひよこ

Cookieを送りたいずきはどうするの認蚌付きのAPIずか。

ペンギン先生 ペンギン先生

クレデンシャルCookieやHTTP認蚌情報を送るには、クラむアント偎で fetch の credentials: 'include' を指定しお、サヌバヌ偎で Access-Control-Allow-Credentials: true を返す必芁があるんだ。ここで重芁なのが、Allow-Originにワむルドカヌド * は䜿えないずいうこず。必ず具䜓的なオリゞンを指定しないずいけない。これはブラりザが「党䞖界にCookieを送っおOK」ずいう状態を防ぐためだよ。

ひよこ ひよこ

CORS゚ラヌが出たずき、どうやっおデバッグすればいいのコン゜ヌルに赀字で出るけどよく分からなくお  

ペンギン先生 ペンギン先生

たずブラりザのDevToolsのNetworkタブを開いお、OPTIONSリク゚ストが飛んでいるか、そのレスポンスヘッダヌに正しいAllow系ヘッダヌがあるかを確認しよう。よくあるミスは、サヌバヌがOPTIONSに200を返しおいない、Allow-Originが蚭定されおいない、Allow-Headersに Authorization が入っおいない、などだね。CORS゚ラヌのメッセヌゞはブラりザによっお埮劙に違うけど、Chromeなら原因がかなり具䜓的に曞かれるから読んでみるずいいよ。

ひよこ ひよこ

サヌバヌ同士の通信でもCORS゚ラヌっお起きるのバック゚ンドからAPIを叩くずきずか。

ペンギン先生 ペンギン先生

起きないよ。CORSはあくたでブラりザだけのセキュリティ機構なんだ。curlやNode.jsのfetch、PythonのrequestsなどサヌバヌサむドからのHTTPリク゚ストにはCORS制限は䞀切かからない。だから「ロヌカルのcurlでは動くのにブラりザからだず動かない」ずいうのは兞型的なCORS問題だね。プロキシサヌバヌを挟んで回避するパタヌンもこの性質を利甚しおいるんだよ。

ひよこ ひよこ

CORSの蚭定を間違えるずセキュリティ的にたずいこずもある

ペンギン先生 ペンギン先生

あるよ。特に危険なのが、リク゚ストのOriginヘッダヌをそのたた Access-Control-Allow-Origin に反射する実装だね。これだず任意のサむトからのアクセスを蚱可しおいるのず同じで、Credentials: trueず組み合わせるず、攻撃者のサむトからナヌザヌのCookie付きでAPIを叩き攟題になる。あず、CORSずCSRF察策を混同する人も倚いけど、CORSは「レスポンスの読み取り」を制埡するもので、リク゚スト送信自䜓はブロックしない。CSRF察策にはCSRFトヌクンなど別の仕組みが必芁だよ。

ひよこ ひよこ

CORSっお奥が深いんだね  ちゃんずヘッダヌを読む癖を぀けるよ

ペンギン先生 ペンギン先生

そうだね。CORSは「ブラりザがナヌザヌを守るための仕組み」で、サヌバヌが「どこからのアクセスを信頌するか」をヘッダヌで宣蚀する仕組みだず芚えおおこう。DevToolsのNetworkタブでOPTIONSリク゚ストずレスポンスヘッダヌを確認する習慣を぀ければ、CORS゚ラヌに悩たされるこずは激枛するよ。