OAuthのstateの役割について説明します。この値は何のためにあるのでしょうか。
stateの用途とは
認可コードリクエストにおいてstateというパラメータは何をしているのでしょうか。
このパラメータはCSRFへの対策をするために存在しています。
CSRFへの対策と言われてもピンと来ないのでOAuthにおけるCSRFについて説明します。
ちなみにCSRF(Cross Site Request Forgery)とは「ユーザーが意図していないリクエストを、ユーザーのブラウザから送らせる攻撃」です。
OAuthにおけるCSRFとは
ここでいうCSRFの内容とは、攻撃者のアカウントで被害者にクライアントの処理をさせることです。
例えば「被害者に攻撃者のアカウントとしてログインさせた上で、攻撃者のアカウントにお金をチャージさせる」という攻撃が挙げられます。
このような攻撃は以下の流れによって行われます。
- ①攻撃者がリダイレクションエンドポイントへのリンクを用意する
- ②被害者にそのリンクを踏ませ、アクセストークンを取得させる
通常の認可コードフロー
まずは攻撃者のいない認可コードフローをおさらいします。
CSRF攻撃を含むフロー
攻撃者が認可レスポンスのリンクを用意し、被害者に踏ませてログインさせるという手口です。
被害者が攻撃者の認可コード付リンクにアクセスすることで、攻撃者のアカウントとしてログインすることになります。
そのまま気づかず攻撃者のアカウントにお金をチャージしてしまうという被害が考えられます。
このような攻撃を防ぐためにstateパラメータが利用されています。
stateの使われ方
stateを使うことでCSRFに対応することができます。
Clientが認可リクエストのパラメータとしてランダムなstateの値を設定すると、認可エンドポイントはリダイレクションエンドポイントのURLにそのままstateの値を付加してくれます。
Webアプリは認可エンドポイントに送ったときのstateとリダイレクションエンドポイントにアクセスしたときのstateを比較してから処理を続行するようにします。攻撃者は正しいstate値を用意できないため、CSRFを防ぐことができます。
まとめ
OAuthの認可コードフローでは、攻撃者が自分の認可コードを被害者に送ることで、被害者を攻撃者のアカウントとしてログインさせるCSRF攻撃が成立します。
stateパラメータは、認可リクエストとリダイレクトレスポンスを紐付けるための値です。
クライアントはランダムなstateを生成し、リダイレクト時に返ってきたstateと比較することで、
「このOAuthフローが自分の開始したものかどうか」を検証できます。
この仕組みにより、攻撃者が用意した認可コードでアクセスするCSRF攻撃を防ぐことができます。