add JSON CSRF protection
This commit is contained in:
parent
ec0df5969b
commit
62dd794011
|
@ -40,6 +40,7 @@ Prevented by:
|
|||
|
||||
* `Rack::Protection::AuthenticityToken` (not included by `use Rack::Protection`)
|
||||
* `Rack::Protection::FormToken` (not included by `use Rack::Protection`)
|
||||
* `Rack::Protection::JsonCsrf`
|
||||
* `Rack::Protection::NoReferrer` (not included by `use Rack::Protection`)
|
||||
* `Rack::Protection::RemoteReferrer` (not included by `use Rack::Protection`)
|
||||
* `Rack::Protection::RemoteToken`
|
||||
|
|
|
@ -8,6 +8,7 @@ module Rack
|
|||
autoload :EscapedParams, 'rack/protection/escaped_params'
|
||||
autoload :FormToken, 'rack/protection/form_token'
|
||||
autoload :FrameOptions, 'rack/protection/frame_options'
|
||||
autoload :JsonCsrf, 'rack/protection/json_csrf'
|
||||
autoload :NoReferrer, 'rack/protection/no_referrer'
|
||||
autoload :PathTraversal, 'rack/protection/path_traversal'
|
||||
autoload :RemoteReferrer, 'rack/protection/remote_referrer'
|
||||
|
@ -21,6 +22,7 @@ module Rack
|
|||
Rack::Builder.new do
|
||||
use EscapedParams, options unless except.include? :escaped_params
|
||||
use FrameOptions, options unless except.include? :frame_options
|
||||
use JsonCsrf, options unless except.include? :json_csrf
|
||||
use PathTraversal, options unless except.include? :path_traversal
|
||||
use RemoteToken, options unless except.include? :remote_token
|
||||
use SessionHijacking, options unless except.include? :session_hijacking
|
||||
|
|
|
@ -41,10 +41,14 @@ module Rack
|
|||
def call(env)
|
||||
unless accepts? env
|
||||
warn env, "attack prevented by #{self.class}"
|
||||
result = send(options[:reaction], env)
|
||||
return result if Array === result and result.size == 3
|
||||
result = react env
|
||||
end
|
||||
app.call(env)
|
||||
result or app.call(env)
|
||||
end
|
||||
|
||||
def react(env)
|
||||
result = send(options[:reaction], env)
|
||||
result if Array === result and result.size == 3
|
||||
end
|
||||
|
||||
def warn(env, message)
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
require 'rack/protection'
|
||||
|
||||
module Rack
|
||||
module Protection
|
||||
##
|
||||
# Prevented attack:: CSRF
|
||||
# Supported browsers:: all
|
||||
# More infos:: http://flask.pocoo.org/docs/security/#json-security
|
||||
#
|
||||
# JSON GET APIs are volnurable to being embedded as JavaScript while the
|
||||
# Array prototype has been patched to track data. Checks the referrer
|
||||
# even on GET requests if the content type is JSON.
|
||||
class JsonCsrf < AuthenticityToken
|
||||
default_reaction :deny
|
||||
|
||||
def call(env)
|
||||
status, headers, body = app.call(env)
|
||||
if headers['Content-Type'].to_s.split(';', 2).first.strip == 'application/json'
|
||||
result = react(env) if referrer(env) != Request.new(env).host
|
||||
end
|
||||
result or [status, headers, body]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
require File.expand_path('../spec_helper.rb', __FILE__)
|
||||
|
||||
describe Rack::Protection::JsonCsrf do
|
||||
it_behaves_like "any rack application"
|
||||
end
|
Loading…
Reference in New Issue