32
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

CSRFトークンはもはや不要です

Posted at

タイトル通りです。CSRFトークンはもはや旧ブラウザへの対応が必要である場合を除いて不要です。CSRFトークンを頑張って実装しなくても、CookieのSameSite属性を用いればCSRFは防御可能です。

CSRFの原因

そもそもCSRFはあるオリジンから別のオリジンへCookie付きのPOSTリクエストを行えてしまうことによって起きる問題でした。たとえばCSRFの脆弱性があるbank.example.comという銀行サイトにログインした状態で、下記のコードが含まれる第三者の悪意あるサイトmalicious.example.comを開いて「今すぐクリック!!!」をクリックすると、お金が勝手に送金されてしまいます。

malicious.example.com
<form action="https://bank.example.com/transfer" method="post">
  <input type="hidden" name="to" value="cracker" />
  <input type="hidden" name="amount" value="¥10000000" />
  <button>今すぐクリック!!!</button>
</form>

問題は何の関係性もないmalicious.example.comのサイトから発せられたbank.example.comへのリクエストにbank.example.comの認証情報(Cookie)が付与されてしまうことです。これによってbank.example.comに対するユーザ認証付きの操作を第三者がそれと分からない形で実行させることができてしまうわけです。

そこで導入されたのがSet-CookieヘッダのSameSite属性です。

SameSite属性

SameSiteSet-Cookieヘッダの属性でたとえば以下のように設定します。

Set-Cookie: sessionId=9284769; SameSite=Lax

SameSite属性の値は3種類、NoneLaxStrictです。

LaxまたはStrictを指定すればCSRFは起こりません。Strictを指定するとブラウザは別オリジンのサイトによって開始されたリクエストではCookieを送信しません。Noneは昔のブラウザと同じ挙動で、常にCookieを送信します。LaxはGETリクエストの場合はNone相当だが、POSTリクエストの場合はStrict相当になるといった設定です。LaxもしくはStrictであれば別の第三者のサイトからのPOSTリクエスト時にはCookieを送信しないのでCSRFは起こり得ません。

上の例のフォームではmalicious.example.com上のサイトから開始されたhttps://bank.example.com/transferへのリクエストは別オリジンへのリクエストとなるためCookieが付与されず、銀行サイトのバックエンドからはユーザ認証がないリクエストとして扱われます。そうなれば当然送金はできずに攻撃は失敗するというわけです。

多くの場合、Strictは厳しすぎるのでLaxを使うことになると思います。Strictを指定した場合、GETメソッドでもCookieが送られないと言うことは、別のサイトに自分のサイトのリンクが貼ってあったとき、それをクリックしてもCookieが送信されない、つまり必ずログインされていない状態で遷移するということです。一般公開しているサイトならそれは不便すぎますよね。

ブラウザサポート状況

SameSite属性はすでにモダンブラウザの全てで、最低でも2,3年前からサポートされています。

Google ChromeではSameSite属性を指定しない場合のデフォルト値がLaxになっています。しかしFirefoxやSafariは互換性重視でデフォルトがNoneなので指定は必須です。

SafariやIE11の数年前のバージョンとマイナーなモバイルブラウザではサポートされないものもあるようです(2023年1月現在)。彼らのためにCSRFトークンを実装してあげるかどうかと言う話ですね。私としては、ここまで普及していて特に難易度が高いとも思えないセキュリティ機能を未だに実装していないようなブラウザはそもそも使うべきではない、と言う感想ですが。

まとめ

  • CSRF対策はSet-CookieヘッダにSameSite=Laxを付与すれば足りる。
  • SameSite属性はモダンブラウザの全てで数年前からサポート済み。
  • CSRFトークンは古かったり一部のマイナーなブラウザへの対応が必要な場合を除いて不要。
32
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?