All Projects → baldowl → Rack_csrf

baldowl / Rack_csrf

Licence: other
Anti-CSRF Rack middleware

Programming Languages

ruby
36898 projects - #4 most used programming language

Labels

Projects that are alternatives of or similar to Rack csrf

Rack Throttle
Rack middleware for rate-limiting incoming HTTP requests.
Stars: ✭ 898 (+431.36%)
Mutual labels:  rack
Rack Host Redirect
Rack middleware to redirect legacy domains
Stars: ✭ 64 (-62.13%)
Mutual labels:  rack
Crepe
The thin API stack.
Stars: ✭ 120 (-28.99%)
Mutual labels:  rack
Open api parser
A parser for Open API specifications
Stars: ✭ 30 (-82.25%)
Mutual labels:  rack
Health bit
Tiny health check of Rack apps like Rails, Sinatra for use with uptime checking systems like Kubernetes, Docker or Uptimerobot
Stars: ✭ 60 (-64.5%)
Mutual labels:  rack
Cuba
Rum based microframework for web development.
Stars: ✭ 1,385 (+719.53%)
Mutual labels:  rack
Agoo
A High Performance HTTP Server for Ruby
Stars: ✭ 679 (+301.78%)
Mutual labels:  rack
Sinatra
Classy web-development dressed in a DSL (official / canonical repo)
Stars: ✭ 11,497 (+6702.96%)
Mutual labels:  rack
Nginx omniauth adapter
Use omniauth for nginx auth_request
Stars: ✭ 63 (-62.72%)
Mutual labels:  rack
Capybara discoball
Spin up an external server just for Capybara
Stars: ✭ 116 (-31.36%)
Mutual labels:  rack
Redis Rack
Redis session store for Rack
Stars: ✭ 46 (-72.78%)
Mutual labels:  rack
Letsencrypt heroku
Automated letsencrypt setup for heroku
Stars: ✭ 58 (-65.68%)
Mutual labels:  rack
As
VCV Rack Modules
Stars: ✭ 104 (-38.46%)
Mutual labels:  rack
Puma
A Ruby/Rack web server built for parallelism
Stars: ✭ 6,924 (+3997.04%)
Mutual labels:  rack
Vite ruby
⚡️ Vite.js in Ruby, bringing joy to your JavaScript experience
Stars: ✭ 112 (-33.73%)
Mutual labels:  rack
Iodine
iodine - HTTP / WebSockets Server for Ruby with Pub/Sub support
Stars: ✭ 720 (+326.04%)
Mutual labels:  rack
Ferrocarril
🚆 Experiments to embed Ruby on Rails in Rust with mruby
Stars: ✭ 66 (-60.95%)
Mutual labels:  rack
Sham rack
run Rack applications in-process, without a server
Stars: ✭ 169 (+0%)
Mutual labels:  rack
Prax.cr
Rack proxy server for development (Crystal port)
Stars: ✭ 142 (-15.98%)
Mutual labels:  rack
Rack Weixin
微信公众平台 开放消息接口 Rack Middleware
Stars: ✭ 105 (-37.87%)
Mutual labels:  rack

= Rack::Csrf {Build Status}[https://travis-ci.org/baldowl/rack_csrf] {CircleCI}[https://circleci.com/gh/baldowl/rack_csrf] {Gem Version}[http://badge.fury.io/rb/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.

Rack::Csrf is not tailored to any particular web framework, so it can be used with your preferred Rack-based framework.

== 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, DELETE and PATCH 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.

The anti-forging token can be passed as a request parameter or a header.

== Options

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

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

use Rack::Csrf, :raise => true

Default value: false.

[:check_only] By default, Rack::Csrf checks every POST, PUT, DELETE and PATCH request; passing an array of HTTP method/URL (regular expressions allowed) to this option you can change this behavior to only check the items on this list.

use Rack::Csrf, :check_only => ['POST:/checking', 'PUT:/me_too',
  'DELETE:/cars/.*\.xml', 'PATCH:/this/.*/too']

Please, note that the regular expressions are not escaped and it is your duty to write them correctly. Empty PATH_INFO (see Rack's spec for details) is treated as '/' for this check.

Default value: empty.

[:skip] By default, Rack::Csrf checks every POST, PUT, DELETE and PATCH request; passing an array of HTTP method/URL (regular expressions allowed) to this option you can choose what to let pass unchecked:

use Rack::Csrf, :skip => ['POST:/not_checking', 'PUT:/me_too',
  'DELETE:/cars/.*\.xml', 'PATCH:/this/.*/too']

Please, note that the regular expressions are not escaped and it is your duty to write them correctly. Empty PATH_INFO (see Rack's spec for details) is treated as '/' for this check.

Default value: empty.

[:skip_if] Sets a lambda/Proc executed on every request to determine if that request should be let pass untouched:

use Rack::Csrf, :skip_if => lambda { |request|
  request.env.key?('HTTP_X_VERY_SPECIAL_HEADER')
}

Your code will receive a request object (see Rack's documentation for details); if it returns anything but nil or false, no further checking is performed and the request is let pass.

This option is useful if a guarded resource can be accessed by clients who support CSRF token (e.g. browsers) and by ones who don't (e.g. API clients).

Don't try to check the CSRF token: it could exist or not at this stage and you should always let it alone.

Default value: empty.

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

use Rack::Csrf, :field => '_my_own_csrf_field'

Default value: _csrf

[:key] The key used to store/retrieve the token from the Rack session; you can adapt it to specific needs.

use Rack::Csrf, :key => 'my.own_session.key'

Default value: csrf.token

[:header] Default header name (see below) is X_CSRF_TOKEN; you can adapt it to specific needs.

use Rack::Csrf, :header => 'MY_CSRF_TOKEN_HEADER'

This is useful if we want to configure our application to send the CSRF token in all of our AJAX requests via a header. We could implement something along the lines of the following:

(function(jQuery) {
  /*
   * Set the CSRF token for each AJAX request, Rack::Csrf handle the rest.
   * Assumes your layout has a metatag with name of "_csrf" and you're
   * using the default Rack:Csrf header setup.
   */
  jQuery.ajaxSetup({
    beforeSend: function(xhr) {
      var token = jQuery('meta[name="_csrf"]').attr('content');
      xhr.setRequestHeader('X_CSRF_TOKEN', token);
    }
  });
}(jQuery));

Default value: X_CSRF_TOKEN

Note that Rack will append "HTTP_" to this value.

[:check_also] By passing an array of uppercase strings to this option you can add them to the list of HTTP methods which "mark" requests that must be searched for the anti-forging token.

use Rack::Csrf, :check_also => %w(WHATEVER YOU WANT EVEN GET)

Default value: empty

The :browser_only option has been removed; you do not need to edit any rackup file because Rack::Csrf simply ignores unknown options. Changes introduced in Rack version 1.1.0 tightened the parsing of POST params, so requests need to have the right Content-Type (or none at all); these Content-Types are exactly those used also by browsers and so there is no use for :browser_only anymore.

The ill devised :browser_only option could have been used to "protect" an API, but I think it might be better to use a combination of :skip and formatted URLs.

== Helpers

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

[Rack::Csrf.key (also Rack::Csrf.csrf_key)] Returns the name of the key used to store/retrieve the token from the Rack session.

Despite this class method, you should never try to retrieve the token with code like env['rack.session'][Rack::Csrf.key]. See the token method below.

[Rack::Csrf.field (also Rack::Csrf.csrf_field)] Returns the name of the field that must be present in the request.

[Rack::Csrf.header (also Rack::Csrf.csrf_header)] Returns the name of the header that must be present in the request.

[Rack::Csrf.token(env) (also 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.tag(env) (also 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.

[Rack::Csrf.metatag(env, options = {}) (also Rack::Csrf.csrf_metatag(env, options = {}))] Given the request's environment, it generates a small HTML fragment to insert the token in a standard metatag within your layout's head with the right value already entered for you.

options is an optional hash that can currently take a +name+ setting, which will alter the metatag's name attribute.

Default name: _csrf

== Working examples

In the +examples+ directory there are some small, working web applications written with different Rack-based frameworks. They are named after the used framework; see the various README files for other details.

== Supported Rubies and Racks

The gemspec shows the minimum Ruby and Rack versions, but Rack::Csrf is tested only with the Rubies and Racks you can see in +.travis.yml+ and .circleci/config.yml. It could work also with older versions, but I decided not to test it against unsupported Rubies and Racks.

== Contributing

If you want to help:

  • fork the project[https://github.com/baldowl/rack_csrf] on GitHub;
  • work in a topic branch;
  • add features/specs for your additions or bug fixes;
  • write your additions/bug fixes;
  • commit;
  • send me a pull request for the topic branch.

If you have any issue, please post them on the {project's issue list}[https://github.com/baldowl/rack_csrf] on GitHub.

== 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.

== Copyright

Copyright (c) 2009, 2010, 2011, 2012, 2014, 2016 Emanuele Vicentini. See LICENSE.rdoc for details.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].