CSRF(クロスサイトリクエストフォージェリ)の成立条件と対応方法
CSRF(クロスサイトリクエストフォージェリ)とは
悪意あるサイトが、ログイン中のユーザーの権限を利用して、意図しないリクエストを別のWebアプリケーションに送信させる攻撃です。
成立の条件
- 被害者がログイン済で、有効なセッションがある(Cookieなどで自動的に認証される)。
- リクエストがセッションベースで許可されている(トークンなどで確認されていない)。
- 攻撃者が仕掛けたページに被害者がアクセスする(攻撃者が仕掛けたリクエストを実行する)。
CSRFが行われるフロー
- ユーザーが正規サイトでログインします。その際に、ログイン状態を保持するセッション情報(session_idなど)をブラウザのCookieに保持する。
- 攻撃者が悪用リクエストを、ユーザーに踏ませる。
- 悪用リクエストをユーザーが正規サイトに送信する。
- ユーザーのブラウザCookieにログインセッションがあるので、正規サイトは悪用リクエストをログインしたユーザーの正式なリクエストと判断して悪用リクエストを受け入れる、
対応方法
成立条件、CSRFのフローから分かるように、CSRF(クロスサイトリクエストフォージェリ)が狙われるのは、「クロスサイトからのリクエスト広さ」と「ログイン状態の管理」です。
CSRFトークンを使う
CSRFトークンを使うことで、正規サイトが生成したリクエストのみに制限することが可能です。
これは、HTMLフォームの送信や、JavaScript の fetch
/ XMLHttpRequest
/ axios
を使ったリクエストなど、Cookieを伴う状態変更リクエストに有効です。
CSRFトークンとは、「このリクエストは正規のページから送られたものだ」とサーバー側で検証するための、ランダムで一意なトークンです。
サーバーはHTMLやJavaScriptを返す際にこのトークンを発行し、フォーム内やJavaScriptコードに埋め込みます。
ユーザーがリクエストを送るときにこのトークンを含めて送信することで、サーバーは「正規サイトから送られたリクエストかどうか」を判定できます。
Referer/Originで制限する
Referer や Origin ヘッダを使うことで、正規のページから送られたリクエストのみを許可することができます。これらのヘッダには、「どこからリクエストが発生したか(送信元のドメイン)」が含まれます。正規ではないサイトからのリクエストは受け付けないことにすることが可能です。
※Referer/Originは偽装することが出来るので、他の対応策と掛け合わせることが重要
CookieでSameSite=Strictの制限をする / ログイン状態の管理
Cookieがクロスサイトから送信されないように制限することが可能です。
CookieでSameSite=Strictを設定することで、他サイトからのリクエストにはCookieが送信されません。つまり、ログイン状態を証明するセッション情報がリクエストされません。
正規ではないサイトにいる際に、ユーザーが悪用リクエストをしてしまいます。例えば、メール文章に含まれる悪用リンクや悪用サイト内に存在するリンクです。非正規サイト(メール・悪用サイト)にいる状態から正規サイトにリクエストすることを制限することが対応可能です。
※SameSite=Strictを利用する場合には、UX観点で制限が増えるのでトレードオフになる
Discussion