railsのCSRF対策について
トークンの生成
Rails new
した後のapp/views/layouts/application.html.erb
に<%= csrf_meta_tags %>
のタグが記述されています。
このcsrf_meta_tags
メソッドは以下の定義がされています。
def csrf_meta_tags
if defined?(protect_against_forgery?) && protect_against_forgery?
[
tag("meta", name: "csrf-param", content: request_forgery_protection_token),
tag("meta", name: "csrf-token", content: form_authenticity_token)
].join("\n").html_safe
end
end
レンダリングされるとする時に以下を行います。
- Sessionにトークンを格納
SessionStore
を設定している場合はそのストアを見に行きます。
- HTMLに暗号化したトークンを出力
以下のようなHTMLが生成されます。
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="vtaJFQ38doX0b7wQpp0G3H7aUk9HZQni3jHET4yS8nSJRt85Tr6oH7nroQc01dM+C/dlDwt5xPff5LwyZcggeg==" />
検証
ユーザーがPOSTリクエストを送信するときに、HTMLに埋められていたCSRFトークンも一緒に送信されます。
RailsのCSRF対策では、以下の2つのトークンが同一か検証します。
-
<meta name="csrf-token" content="vtaJFQ38doX0b7wQpp0G3H7aUk9HZQni3jHET4yS8nSJRt85Tr6oH7nroQc01dM+C/dlDwt5xPff5LwyZcggeg==" />
に埋め込まれたトークンvtaJFQ38doX0b7wQpp0G3H7aUk9HZQni3jHET4yS8nSJRt85Tr6oH7nroQc01dM+C/dlDwt5xPff5LwyZcggeg==
-
Sessionで保持しているトークン
参考
記事
RailsGuide
Rails/Rails
検証
CSRFトークン生成