Origin 反射と資格情報
ログイン中の利用者のブラウザが行ったクロスオリジンの fetch(credentials を include に設定)に対し,ある API が次のように応答した。API のセッション Cookie には SameSite=None と Secure が付与されている。この CORS 設定のリスクに関する記述として,適切なものはどれか。
リクエスト: Origin: https://attacker.example.net
応答:
Access-Control-Allow-Origin: https://attacker.example.net
Access-Control-Allow-Credentials: true- アクロスオリジンの fetch ではブラウザが Cookie を一切送らないので,資格情報付きの応答が攻撃者に読まれることはない。
- イCORS は要求元のオリジンを制限する仕組みなので,この応答ヘッダによって CSRF 攻撃も同時に防止される。
- ウサーバが要求の Origin ヘッダの値をそのまま反射し,かつ資格情報の共有を許可しているため,攻撃者のサイトを開いた利用者の認証済みの応答を攻撃者のスクリプトが読み取れる。
- エAccess-Control-Allow-Origin に具体的なオリジンが入っている限り,たとえ攻撃者のオリジンでも,プリフライトで必ず拒否されるので実際の要求は送られない。
正解と解説を見る
正解 ウ
この問題の基礎知識
- 同一オリジンポリシーは,あるオリジン(スキーム・ホスト・ポートの組)のページのスクリプトが,異なるオリジンの応答を読み取ることを制限するブラウザの仕組みである。
- CORS は,サーバが Access-Control-Allow-Origin などの応答ヘッダで読取りを許可するオリジンを示し,ブラウザがそれに従って応答をスクリプトに渡すかを決める仕組みである。プリフライトが不要な単純要求はそのまま送信されるので,要求の送信を防ぐ仕組みではない。
- Cookie などの資格情報付きの要求の応答を読ませるには,Access-Control-Allow-Credentials: true と,ワイルドカード(*)ではない具体的なオリジンの指定が必要になる。
- Cookie の SameSite 属性が None(Secure 必須)の場合は,仕様上クロスサイトの要求にも Cookie が送られる。CSRF は要求を送らせる攻撃であり,応答の読取りを制御する CORS とは対策が別である。
credentials を include にしたクロスオリジン要求では Cookie が送信される。同一オリジンポリシーで Cookie が送られないという思い込みで,この設定の危険性を見落としている。
CORS は応答を読み取れるオリジンを制御するもので,要求の送信自体は止めない。CSRF の防止は別途必要であり,CORS と CSRF 対策の役割を混同している。
Origin を無検査で反射し Access-Control-Allow-Credentials: true を返すと,任意のオリジンが資格情報付きで応答を読める。許可するオリジンは信頼できるものだけを明示的に照合すべきである。
単純要求(GET など)はプリフライトされずに実際の要求が送られるので,必ず拒否されるとはいえない。具体的なオリジンが入っていれば安全という誤解であり,Origin を反射するサーバでは攻撃者のオリジンも許可される。
照合の根拠(6 件)
- ア(誤り): credentials mode が include の要求には常に資格情報(Cookie など)が含まれる
" include " Always includes credentials with this request, and always use any credentials sent back in the response.
Fetch Standard (WHATWG) · Requests(credentials mode)(新しいタブで開きます) - ア(誤り)・前提: SameSite=None(Secure 付き)の Cookie はクロスサイトの要求にも送られる
- `None` - : Send the cookie with both cross-site and same-site requests. The `Secure` attribute must also be set when using this value.
MDN Set-Cookie · Attributes: SameSite=None(新しいタブで開きます) - ウ(正解): Access-Control-Allow-Origin が要求のオリジンと一致し,Access-Control-Allow-Credentials が true なら資格情報付きでも CORS チェックは成功する。Origin を反射するサーバでは攻撃者のオリジンでも成功し,応答を読まれる
If the result of byte-serializing a request origin with request is not origin , then return failure. If request 's credentials mode is not " include ", then return success. Let credentials be the result of getting ` Access-Control-Allow-Credentials ` from response 's header list . If credentials is ` true `, then return success.
Fetch Standard (WHATWG) · CORS check(新しいタブで開きます) - ウ(正解): Origin ヘッダの値を検査せずに返すことは避け,信頼するドメインだけを許可すべきである
Allow only selected, trusted domains in the Access-Control-Allow-Origin header. Prefer allowing specific domains over blocking or allowing any domain (do not use * wildcard nor blindly return the Origin header content without any checks).
OWASP HTML5 Security Cheat Sheet · Cross Origin Resource Sharing(新しいタブで開きます) - イ(誤り): CORS は CSRF を防がず,通常の CSRF 対策が別途必要である
Keep in mind that CORS does not prevent the requested data from going to an unauthorized location. It's still important for the server to perform usual CSRF prevention.
OWASP HTML5 Security Cheat Sheet · Cross Origin Resource Sharing(新しいタブで開きます) - エ(誤り): プリフライトされない要求(単純要求)があり,その場合は実際の要求がそのまま送られる
Some requests don't trigger a {{Glossary("Preflight_request","CORS preflight")}}.
MDN Cross-Origin Resource Sharing (CORS) · Simple requests(新しいタブで開きます)
Fetch Standard は fetch.spec.whatwg.org が取得できないため,同じ標準のソース(whatwg/fetch の fetch.bs)で照合した。サードパーティ Cookie を既定で制限するブラウザでは送られない場合もあるが,問題は SameSite=None の Cookie が仕様上送られる前提での CORS 設定のリスクを問うており,正解は変わらない。