my_back_pages

プログラミング学習の記録 Ruby / Rails / FjordBootCamp

【Rails】(メモ)React + Rails(API)でよく考えずに skip_before_action :verify_authenticity_token するのは危なそう

React + Rails(API)構成でのアプリ開発について学習している中で、下のようなコードと出会いました。

# app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  include DeviseTokenAuth::Concerns::SetUserByToken

  skip_before_action :verify_authenticity_token
end

RailsCSRF攻撃対策

  • 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が使われているみたい。)

railsguides.jp

一方、ビューを使わない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