class Rack::Csrf

Constants

VERSION

Public Class Methods

csrf_field()
Alias for: field
csrf_header()
Alias for: header
csrf_key()
Alias for: key
csrf_metatag(env, options = {})
Alias for: metatag
csrf_tag(env)
Alias for: tag
csrf_token(env)
Alias for: token
field() click to toggle source
   # File lib/rack/csrf.rb
49 def self.field
50   @@field
51 end
Also aliased as: csrf_field
header() click to toggle source
   # File lib/rack/csrf.rb
53 def self.header
54   @@header
55 end
Also aliased as: csrf_header
key() click to toggle source
   # File lib/rack/csrf.rb
45 def self.key
46   @@key
47 end
Also aliased as: csrf_key
metatag(env, options = {}) click to toggle source
   # File lib/rack/csrf.rb
65 def self.metatag(env, options = {})
66   name = options.fetch(:name, '_csrf')
67   %Q(<meta name="#{name}" content="#{token(env)}" />)
68 end
Also aliased as: csrf_metatag
new(app, opts = {}) click to toggle source
   # File lib/rack/csrf.rb
13 def initialize(app, opts = {})
14   @app = app
15 
16   @raise_if_invalid = opts.fetch(:raise, false)
17   @skip_list        = opts.fetch(:skip, []).map {|r| /\A#{r}\Z/i}
18   @skip_if          = opts[:skip_if]
19   @check_only_list  = opts.fetch(:check_only, []).map {|r| /\A#{r}\Z/i}
20   @@field           = opts[:field] if opts[:field]
21   @@header          = opts[:header] if opts[:header]
22   @@key             = opts[:key] if opts[:key]
23 
24   standard_http_methods = %w(POST PUT DELETE PATCH)
25   check_also            = opts.fetch(:check_also, [])
26   @http_methods = (standard_http_methods + check_also).flatten.uniq
27 end
tag(env) click to toggle source
   # File lib/rack/csrf.rb
61 def self.tag(env)
62   %Q(<input type="hidden" name="#{field}" value="#{token(env)}" />)
63 end
Also aliased as: csrf_tag
token(env) click to toggle source
   # File lib/rack/csrf.rb
57 def self.token(env)
58   env['rack.session'][key] ||= SecureRandom.urlsafe_base64(32)
59 end
Also aliased as: csrf_token

Protected Class Methods

rackified_header() click to toggle source

Returns the custom header's name adapted to current standards.

   # File lib/rack/csrf.rb
82 def self.rackified_header
83   "HTTP_#{@@header.gsub('-', '_').upcase}"
84 end

Public Instance Methods

call(env) click to toggle source
   # File lib/rack/csrf.rb
29 def call(env)
30   unless env['rack.session']
31     fail SessionUnavailable, 'Rack::Csrf depends on session middleware'
32   end
33   req = Rack::Request.new(env)
34   let_it_pass = skip_checking(req) ||
35     !@http_methods.include?(req.request_method) ||
36     found_a_valid_token?(req)
37   if let_it_pass
38     @app.call(env)
39   else
40     fail InvalidCsrfToken if @raise_if_invalid
41     [403, {'Content-Type' => 'text/html', 'Content-Length' => '0'}, []]
42   end
43 end

Protected Instance Methods

any?(list, request) click to toggle source

Returns true when the given list “includes” the request.

    # File lib/rack/csrf.rb
 99 def any? list, request
100   pi = request.path_info.empty? ? '/' : request.path_info
101   list.any? do |route|
102     route =~ (request.request_method + ':' + pi)
103   end
104 end
found_a_valid_token?(request) click to toggle source
    # File lib/rack/csrf.rb
106 def found_a_valid_token? request
107   token = self.class.token(request.env)
108   Rack::Utils.secure_compare(request.params[self.class.field].to_s, token) ||
109     Rack::Utils.secure_compare(request.env[self.class.rackified_header].to_s, token)
110 end
skip_checking(request) click to toggle source

Returns true if the given request appears in the skip list or the conditional skipping code return true or, when the check only list is not empty (i.e., we are working in the “reverse mode” triggered by the check_only option), it does not appear in the check only list.

   # File lib/rack/csrf.rb
91 def skip_checking request
92   to_be_skipped = any? @skip_list, request
93   to_be_skipped ||= @skip_if && @skip_if.call(request)
94   to_be_checked = any? @check_only_list, request
95   to_be_skipped || (!@check_only_list.empty? && !to_be_checked)
96 end