React + Rails(API)構成でのアプリ開発について学習している中で、下のようなコードと出会いました。
# app/controllers/application_controller.rb class ApplicationController < ActionController::Base include DeviseTokenAuth::Concerns::SetUserByToken skip_before_action :verify_authenticity_token end
RailsのCSRF攻撃対策
- Railsは、CSRF攻撃対策のためのトークンを生成し、セッションで
_csrf_token
というキーでユーザーに保持させる。 - デフォルトでは、
rails new
で自動生成されるビューであるapplication.html.erb
上のメタタグ<%= csrf_meta_tags %>
によって、_csrf_token
の中のトークンは生成される。 form_with
による値の送信の際に、上のトークンを暗号化したauthenticity_token
が生成され、他の値と一緒に送られる。verify_authenticity_token
は、上の2つが一致しているかを検証するメソッド。違っていたら不正なリクエストと判断される。
ビューを用いたスタンダードなRailsアプリ開発では、これらの仕組みのおかげで特に意識することなくCSRF攻撃対策ができている模様です。
そのために、verify_authenticity_token
というメソッドはとても大事だというわけですね。
(実際は、これのラッパーのprotect_from_forgery
が使われているみたい。)
一方、ビューを使わないAPIモードの場合、
そもそも検証すべきトークンが生成されない → POSTリクエストが送られてもverify_authenticity_token
による検証が失敗する → Can't verify CSRF token authenticity
というエラーが起きる
という現象が起きてしまうようです。
それを回避するために、トークン検証自体をやらないようにしよう!というのが、冒頭のskip_before_action :verify_authenticity_token
の意味だったみたいです。
(デモ用のコードだからということだとは思いますが、単純なエラー解消手段としてこれを紹介する記事もあったりするみたいなので、セキュリティ関係のことは念を入れて気をつけておかねばと思った次第です。)
どうすべきなのか
トークンを自動生成するビューがないのであれば、「トークンを生成してクライアント側に渡す -> 受け取ったクライアントは以後そのトークンをリクエストにのっける」という仕組みを自前で作る必要があるということみたいです。
実際に必要になったら、下の記事などをもとに対応したいと思っていますが、現時点での上記の仕組みと注意点の備忘録的な記事でした。
参考にさせていただきました🙏
RailsにおけるCSRF対策をできるだけ分かりやすく説明する
【Rails API】CSRF 対策をあきらめないでちゃんとやる | みどりみちのブログ
React + Rails(API)で tokenを用いたCSRF対策の基礎(のメモ) - jonamon’s diary