CSRF周りメモ(with NextAuth)
/api/auth/sessionで返却される電文は、JWSの中にあるものから選ぶ事ができる
Authraizationヘッダー + localStorage
=> XSS怖い
Authraizationヘッダー + Cookie(not HTTP Only属性)
=> CSRF怖いのでAuthraizationヘッダーを使うと、CookieにHTTP only属性は使えない。。(XSS怖い)
Cookie認証 + Cookie(HTTP Only属性+Same site(Lax,Strict))
=> XSS,CSRF対策出来てそう
3つ目ってやっぱり、CSRF対策としては何もできてないよね。
NextAuthはここら辺/api/auth/sessionエンドポイントでJWSの平文を返却してくれる。
フロント側は、これをベアラートークンに設定して別APIを叩くからCSRF対策になる。
試しに、localhost:3002->example.comに対してGETリクエストをしているんだけどどういうわけかcookieが射出されない。SameSite=Lax;Secure;HttpOnly;で、fetchはこんな感じなんだけど、、
const response = await fetch(
'https://example.com/api/auth/session',
{
mode: 'cors',
credentials: 'include',
},
);
const data = await response.json();
リクエスト自体は単純リクエストなんだけどなぁ(一部改変)
curl 'https://example.com/api/auth/session' \
-H 'accept: */*' \
-H 'accept-language: ja,en-US;q=0.9,en;q=0.8' \
-H 'origin: http://localhost:3002' \
-H 'referer: http://localhost:3002/' \
-H 'sec-ch-ua: "Chromium";v="112", "Google Chrome";v="112", "Not:A-Brand";v="99"' \
-H 'sec-ch-ua-mobile: ?1' \
-H 'sec-ch-ua-platform: "Android"' \
-H 'sec-fetch-dest: empty' \
-H 'sec-fetch-mode: cors' \
-H 'sec-fetch-site: cross-site' \
-H 'user-agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36' \
--compressed
およ?DevtoolでSameSite=LaxからNoneに変えたら飛んだわ。
SameSite=Lax の場合、クロスサイトのリクエストで Cookie が送信される状況は限定的です。主に次のような場合に Cookie が含まれます。
* リンクをクリックしてナビゲートする場合
* GET メソッドのフォーム送信の場合
* プリロード要求の場合
しかし、fetch や XMLHttpRequest でクロスサイトリクエストを行う場合、SameSite=Lax では Cookie は含まれません。これは、fetch や XMLHttpRequest によるリクエストが上記の条件に該当しないためです。
一方、SameSite=None に設定された場合、ブラウザは、リクエストの種類に関係なく、クロスサイトリクエストで Cookie を送信します。ただし、これにより CSRF のリスクが高まるため、他のセキュリティ対策を適切に実装することが重要です。
例として、fetch を使って SameSite=Lax の Cookie を送信しようとしても、ブラウザは Cookie を含めずにリクエストを送信します。これが、SameSite=None では Cookie が送信されるが、SameSite=Lax では送信されない理由です。
あとちゃんとクロスオリジンでcookie送りたい場合は、サーバー側でCORS設定が必要やね。
そのため、サーバ側ではAccess-Control-Allow-Credentialsをtrueとして返すように設定しなければいけません。
クロスオリジンでsameSite=Laxで飛ぶ条件
結論として
top-levelリクエストで、かつ、GETリクエストであるものにCookieが付与される。
だね
このように strict だとクロスオリジンなリクエストではCookieが送信されないため、CSRF攻撃の緩和につながる。
一方でリンクを辿るだけでもCookieが送信されないため、それはそれで不便。
一方でリンクを辿るだけでもCookieが送信されないため、それはそれで不便。
これってどんなケースなんだろう?イメージできない。
例えば、Aサイトでログイン中だった場合に、Bサイト上に用意されたAサイトへのリンクをクリックした場合、ログイン状態でページの遷移が行われます
ページ遷移するときに認証情報が抜けてるってこと?そんなことあるのか。
Aサイトでログイン中だった場合に、Bサイト上に用意されたAサイトへのリンクをクリックした場合、Aサイトにクッキーが送られませんので、Aサイトに対して未ログイン状態の扱いでページの遷移が行われます。当然、この動作は不便な面もあります。
実体験としてあったかなぁ、、
NextAuthの場合遷移したら、/api/auth/sessionをクライアントから叩くから再現しないのかな。
cookie情報をもとに認証情報のレンダリングして返している場合は、ワークしないかもね。
なるほど〜
結局Aタグってクロスドメインのリクエストなんだよね
aサイトbサイトがあって、bにログイン済みの場合、Aタグでbサイトに遷移するときaからbにリクエストしてるわけだし。
そりゃstrictならcookie飛ばないや。
nextauthそこらへんクライアントサイドでAPI叩くことで解消してるようにみえるけど、、詳しいところは謎
- GETはクロスドメインでも実行されてしまう(SameSite=strictにすれば防げるが、Google検索からの初回リクエストでcookieが飛ばずログアウト状態になるので実質)
- GETで重要な処理をしない
- Origin検証、CSRFトークンで対策をする