Rack::Csrf

This is just a small Rack middleware whose only goal is to lessen the hazards posed by CSRF attacks by trying to ensure that all requests of particular types come from the right client, not from a mischievous impersonator.

Usage

First of all, beyond Rack itself, there is only one prerequisite: you must set up your rack with a session middleware, inserted anywhere before Rack::Csrf.

Every POST, PUT and DELETE request will be searched for the anti-forging token, randomly generated by Rack::Csrf and stored inside the session. If there’s a token and it matches with the stored one, then the request is handed over to the next rack component; if not, Rack::Csrf immediately replies with an empty response.

I have not tested Rack::Csrf with Rack 0.4.0 or earlier versions, but it could possibly work.

Options

The following options allow you to tweak Rack::Csrf.

:raise

Set it to true to change the handling of bad request: instead of producing an empty response, Rack::Csrf will raise an exception of class Rack::Csrf::InvalidCsrfToken.

:skip

By default, Rack::Csrf checks every POST, PUT and DELETE request; passing an array of HTTP method/URL to this option you can choose what to let pass unchecked:

use Rack::Csrf, :skip => ['POST:/not_checking', 'PUT:/me_too']
:field

Default field name (see below) is _csrf; you can adapt it to specific needs.

Helpers

The following class methods try to ease the insertion of the anti-forging token.

Rack::Csrf.csrf_field

Returns the name of the field that must be present in the request.

Rack::Csrf.csrf_token(env)

Given the request’s environment, it generates a random token, stuffs it in the session and returns it to the caller or simply retrieves the already stored one.

Rack::Csrf.csrf_tag(env)

Given the request’s environment, it generates a small HTML fragment to insert the token in a standard form like an hidden input field with the right value already entered for you.

Working examples

In the example directory there is a mini Sinatra application with two slightly different rackup files. Beside Rack you only need Sinatra to try them, but Rack::Csrf is not tailored to any particular web framework.

Warning! Warning! Warning!

I cannot stress enough that this middleware is not a bulletproof vest or a panacea for the CSRF plague; it is just an aid and by using it you cannot forgo responsibilities for keeping your application as safe as possible.