Class: Rack::Protection::JsonCsrf

Inherits:
Base
  • Object
show all
Defined in:
lib/rack/protection/json_csrf.rb

Overview

Prevented attack

CSRF

Supported browsers

all

More infos

flask.pocoo.org/docs/0.10/security/#json-security haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx

JSON GET APIs are vulnerable to being embedded as JavaScript when the Array prototype has been patched to track data. Checks the referrer even on GET requests if the content type is JSON.

If request includes Origin HTTP header, defers to HttpOrigin to determine if the request is safe. Please refer to the documentation for more info.

The ‘:allow_if` option can be set to a proc to use custom allow/deny logic.

Constant Summary

Constants inherited from Base

Base::DEFAULT_OPTIONS

Instance Attribute Summary

Attributes inherited from Base

#app, #options

Instance Method Summary collapse

Methods inherited from Base

#accepts?, #default_options, default_options, default_reaction, #deny, #drop_session, #encrypt, #html?, #initialize, #instrument, #origin, #random_string, #referrer, #report, #safe?, #secure_compare, #session, #session?, #warn

Constructor Details

This class inherits a constructor from Rack::Protection::Base

Instance Method Details

#call(env) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/rack/protection/json_csrf.rb', line 24

def call(env)
  request               = Request.new(env)
  status, headers, body = app.call(env)

  if has_vector?(request, headers)
    warn env, "attack prevented by #{self.class}"

    react_and_close(env, body) or [status, headers, body]
  else
    [status, headers, body]
  end
end

#close_body(body) ⇒ Object



52
53
54
# File 'lib/rack/protection/json_csrf.rb', line 52

def close_body(body)
  body.close if body.respond_to?(:close)
end

#has_vector?(request, headers) ⇒ Boolean

Returns:

  • (Boolean)


37
38
39
40
41
42
# File 'lib/rack/protection/json_csrf.rb', line 37

def has_vector?(request, headers)
  return false if request.xhr?
  return false if options[:allow_if] && options[:allow_if].call(request.env)
  return false unless headers['Content-Type'].to_s.split(';', 2).first =~ /^\s*application\/json\s*$/
  origin(request.env).nil? and referrer(request.env) != request.host
end

#react_and_close(env, body) ⇒ Object



44
45
46
47
48
49
50
# File 'lib/rack/protection/json_csrf.rb', line 44

def react_and_close(env, body)
  reaction = react(env)

  close_body(body) if reaction

  reaction
end