あなたはAPI通信におけるCSRFトークンの仕組みを正しく説明できますか?
最近はSPA(シングルページアプリケーション)など、APIを利用する機会が増えています。当記事では、APIとの通信におけるCSRFトークン(X-CSRF-TOKEN)の役割について解説します。
CSRFトークン、意味ないんじゃない?
CSRF(Cross-site Request Forgery)トークンとは、正規のページからアクセスが行われていることを証明するための値のことです。いわば「合言葉」のようなもので、CSRFトークンが必要となるバックエンドと通信する際は、必ずCSRFトークンを事前に取得しておき、バックエンドへアクセスするときはCSRFトークンも一緒に渡す必要があります。
SPA・APIにおいては、多くの場合、X-CSRF-TOKENという値がクッキーがセットされ、サーバーへ送信する際に一緒に送られるようになっています。CSRFトークンが渡されていない、または正しくないときはサーバー側でアクセスを拒否することで、不正なクライアントからのアクセスを防ぐことができます。
しかし、これに対しある疑問が投げかけられました。
「でもこれだけだと、不正なフロントエンドからもアクセスできちゃうんじゃないですか?偽物のフロントエンドにもトークンを要求する実装をしておけば、バックエンドへアクセスできるようになっちゃうんじゃないですか?」と。
あれれ?たしかに(・∀・;)・・・いやいや、違いますよ!
バックエンドに正規のフロントエンドの情報が設定されているのが肝
ここで重要なのは、CSRFトークンは正規のフロントエンドかどうかをチェックしてから返されるという点です。
誰ふり構わずCSRFトークンを返していては、質問のとおり、まったく意味がありません。偽物フロントエンドからのトークン要求にも答えてしまっては、不正なフロントエンドからもバックエンドへアクセスできてしまいます。これではトークンの意味がないですよね。
なので、バックエンドはCSRFトークンを要求されると、正規のフロントエンドから要求されているかを確認するようにしています。
バックエンドにはあらかじめCSRFトークンの発行を許可するドメインやオリジンなどを設定しておき、正式なフロントエンドからの通信かどうかを確認できるようにしておきます。トークンを要求されたら、Originなどのヘッダー情報が事前に設定してあるものと一致するか照合し、問題なければCSRFトークンを発行するしくみとなっているのです。
もちろん、照合に失敗すれば、不正なクライアントと判定され、トークンは発行されないようになっています。こうすることで、正規のフロントエンドと不正なクライアントを識別することができるようになっているのです。
トークンのやり取りばかりに注目していると、なぜ偽のフロントエンドを識別できるかがわからなくなってしまいます。トークンを生成するか否かを判断し、正式なアクセスのときだけトークンを返すという仕組みが肝なのです。
まとめ
フォームに埋め込むタイプのCSRFならともかく、SPAやAPI通信におけるCSRFのしくみは、少しわかりにくいものとなっています。
クライアント側からトークンを要求された際に、正規のクライアントかどうかを判定するところがポイントです。
ここが分かれば、CSRFの意義がすんなりと理解できると思います。
コメント