LoginSignup
7
1

More than 1 year has passed since last update.

知らないうちに僕たちは Ruby on Rails に CSRF から守られている

Last updated at Posted at 2022-05-31

前提

Cloud CIRCUS Meetup に登壇した際に話した内容を記事にしました.
Meetup のアーカイブは以下に上がっています.

本記事は, Ruby on Rails で作成したプロジェクトが, どのように CSRF から私たちを守ってくれているのかの全体像を なんとなく 掴むところをゴールとして構成されています.
そのため, Rails 自体のソースコードの詳しい解説や, その他のセキュリティ対策に関することはスコープ外とします.

登壇した際に使用したスライドは以下で公開しています.

CSRF とは

Cross Site Request Forgery の頭文字を取ったもので, 利用者が意図しないリクエストを攻撃対象の Web サーバに送ってしまう脆弱性及びその脆弱性を利用した攻撃方法のことを指します.

具体的な例としては, ユーザがなにかの EC サイトにログインしている状態で
攻撃者が用意した Web アプリケーションに訪問すると, EC サイトに保持されているセッション情報を使用して, 意図しない商品の購入などが実行されてしまうなどが挙げられます.

図解

本来のながれ

image.png
image.png
image.png

攻撃のながれ

image.png
image.png
image.png
image.png

Rails はどのように僕たちを守っているのか

Rails では, HTML - セッション Cookie に 一意のトークン ( csrf_token ) を埋め込むことで CSRF 対策をしています.

一意のトークンは, デフォルトで authenticity_token というキー名で使用されます.

image.png

発行のながれ

app/views/layouts/application.html.erbhead 内で HTML へ埋め込んでいます.

image.png

rails の csrf_meta_tags メソッドは actionview/lib/action_view/helpers/csrf_helper.rb 内に定義されており, トークン発行処理は form_authenticity_token に実装されています (登壇資料作成に当たってそれなりに潜りましたが詳細の解説は本記事では割愛します) .

image.png

form_authenticity_token が呼び出されると, 以下のような流れでトークン発行を実行します.

  1. ランダムな文字列を Base64 形式で生成し, セッションに格納します.
  2. ランダムなバイト列でワンタイムパッドを生成.
  3. ワンタイムパッドとセッションに格納された文字列をデコードした値を XOR 操作することによって暗号化します.
  4. ワンタイムパッドを暗号化した文字列の先頭に付加します (先頭にワンタイムパッドを仕込むことで復号可能な文字列となります) .
  5. view に埋め込むため, 先程生成した文字列をエンコードします.

以上の手順で csrf_token の view への埋め込みと, セッション cookie への格納を実行しています.

照合のながれ

Rails5 以降はデフォルトでオンになっているため, このような記述はされていませんが, protect_from_forgery メソッドを呼び出すことで リクエストごと1csrf_token の照合を実行します.

image.png

protect_from_forgery が呼び出されると, 以下のような流れでトークン照合を実行します.

  1. パラメータのトークン ( authenticity_token ) をデコードします.
  2. トークン先頭のワンタイムパッドを使用して発行時と同じロジックでマスクを解除します.
  3. マスク解除した文字列とセッション cookie をデコードした値で照合します.
  4. 照合が通過すれば以降の処理が実行されます.

上記のような処理をリクエストごとに実行することで, CSRF からアプリケーションを守ってくれるような仕組みとなっています.

まとめ

今回は Rails の CSRF 対策の全体像について執筆しましたが, Rails 以外の Web フレームワークでも同様に様々な機能が実装されています.

「なぜこのような記述がされているのか?」というところを
突き詰めてみると面白いですし, 実際の開発でも役に立つことがあるかもしれません.

  1. POST リクエストのみ検証するなどの条件があります.

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1