Techioz Blog

Rails Authenticity トークンについて

概要

Rails の認証トークンとは何ですか?

解決策

何が起こるのですか

ユーザーがリソースを作成、更新、または破棄するためにフォームを表示すると、Rails アプリはランダムなAuthenticity_tokenを作成し、このトークンをセッションに保存し、フォームの非表示フィールドに配置します。ユーザーがフォームを送信すると、Rails はauthenticity_token を探し、セッションに保存されているものと比較し、一致する場合はリクエストの続行が許可されます。

なぜそれが起こるのか

認証トークンはセッションに保存されるため、クライアントはその値を知ることができません。これにより、Rails アプリ自体内でフォームを表示せずに、Rails アプリにフォームを送信することができなくなります。 サービス A を使用していて、サービスにログインし、すべてが正常であると想像してください。ここで、サービス B を利用し、気に入った写真を見つけ、その写真を押して大きなサイズで表示したとします。ここで、サービス B に何らかの悪意のあるコードがあった場合、http://serviceA.example/close_account にリクエストを送信して、サービス A (ログインしている) にリクエストを送信し、アカウントの削除を要求する可能性があります。これは、CSRF (クロスサイト リクエスト フォージェリ) として知られているものです。

サービス A が認証トークンを使用している場合、サービス B からのリクエストには正しい認証トークンが含まれておらず、続行が許可されないため、この攻撃ベクトルは適用できなくなります。

API ドキュメントにはメタ タグの詳細が記載されています。

ノート

Rails はべき等でないメソッド (POST、PUT/PATCH、DELETE) のみを検証することに注意してください。 GET リクエストでは、認証トークンがチェックされません。なぜ? HTTP 仕様では、GET リクエストは冪等であり、サーバーでリソースを作成、変更、または破棄してはならないと規定されており、リクエストは冪等である必要があるためです (同じコマンドを複数回実行した場合、毎回同じ結果が得られるはずです)。

また、実際の実装は最初に定義したようにもう少し複雑で、セキュリティが向上します。 Rails は、すべてのフォームで同じ保存されたトークンを発行するわけではありません。また、毎回異なるトークンを生成して保存することもありません。ページがレンダリングされるたびに、セッション内で暗号化ハッシュを生成して保存し、保存されているトークンと照合できる新しい暗号化トークンを発行します。 request_forgery_protection.rb を参照してください。

レッスン

authenticity_token を使用して、べき等でないメソッド (POST、PUT/PATCH、および DELETE) を保護します。また、サーバー上のリソースを変更する可能性のある GET リクエストを許可しないようにしてください。

GET リクエストが冪等であることに関する @erturne のコメントを確認してください。彼は私がここで説明したよりもわかりやすい方法でそれを説明しています。