This extension is part of the Rack::Protection project. Run gem install rack-protection to have it available.


Prevented attack

CSRF

Supported browsers

all

More infos

en.wikipedia.org/wiki/Cross-site_request_forgery

</dl>

This middleware only accepts requests other than GET, HEAD, OPTIONS, TRACE if their given access token matches the token included in the session.

It checks the X-CSRF-Token header and the POST form data.

It is not OOTB-compatible with the rack-csrf gem. For that, the following patch needs to be applied:

Rack::Protection::AuthenticityToken.default_options(key: "csrf.token", authenticity_param: "_csrf")

Options

:authenticity_param

the name of the param that should contain the token on a request. Default value: "authenticity_token"

:key

the name of the param that should contain

the token in the session. Default value:
<tt>:csrf</tt>
:allow_if

a proc for custom allow/deny logic. Default value:

<tt>nil</tt>
</dl>

Example: Forms application

To show what the AuthenticityToken does, this section includes a sample program which shows two forms. One with, and one without a CSRF token The one without CSRF token field will get a 403 Forbidden response.

Install the gem, then run the program:

gem install 'rack-protection'
puma server.ru

Here is server.ru:

require 'rack/protection'
require 'rack/session'

app = Rack::Builder.app do
  use Rack::Session::Cookie, secret: 'CHANGEMEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
  use Rack::Protection::AuthenticityToken

  run -> (env) do
    [200, {}, [
      <<~EOS
        <!DOCTYPE html>
        <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <title>rack-protection minimal example</title>
        </head>
        <body>
          <h1>Without Authenticity Token</h1>
          <p>This takes you to <tt>Forbidden</tt></p>
          <form action="" method="post">
            <input type="text" name="foo" />
            <input type="submit" />
          </form>

          <h1>With Authenticity Token</h1>
          <p>This successfully takes you to back to this form.</p>
          <form action="" method="post">
            <input type="hidden" name="authenticity_token" value="#{Rack::Protection::AuthenticityToken.token(env['rack.session'])}" />
            <input type="text" name="foo" />
            <input type="submit" />
          </form>
        </body>
        </html>
      EOS
    ]]
  end
end

run app

Example: Customize which POST parameter holds the token

To customize the authenticity parameter for form data, use the :authenticity_param option:

use Rack::Protection::AuthenticityToken, authenticity_param: 'your_token_param_name'