2012-01-30 08:57:03 +00:00
|
|
|
require 'rack/protection'
|
|
|
|
|
|
|
|
module Rack
|
|
|
|
module Protection
|
|
|
|
##
|
|
|
|
# Prevented attack:: CSRF
|
|
|
|
# Supported browsers:: Google Chrome 2, Safari 4 and later
|
|
|
|
# More infos:: http://en.wikipedia.org/wiki/Cross-site_request_forgery
|
|
|
|
# http://tools.ietf.org/html/draft-abarth-origin
|
|
|
|
#
|
|
|
|
# Does not accept unsafe HTTP requests when value of Origin HTTP request header
|
2020-07-11 16:01:34 +00:00
|
|
|
# does not match default or permitted URIs.
|
2016-08-01 07:32:11 +00:00
|
|
|
#
|
2020-07-11 16:29:05 +00:00
|
|
|
# If you want to permit a specific domain, you can pass in as the `:permitted_origins` option:
|
2016-08-01 07:32:11 +00:00
|
|
|
#
|
2020-07-11 16:29:05 +00:00
|
|
|
# use Rack::Protection, permitted_origins: ["http://localhost:3000", "http://127.0.01:3000"]
|
2016-08-01 07:32:11 +00:00
|
|
|
#
|
|
|
|
# The `:allow_if` option can also be set to a proc to use custom allow/deny logic.
|
2012-01-30 08:57:03 +00:00
|
|
|
class HttpOrigin < Base
|
2012-12-12 10:03:07 +00:00
|
|
|
DEFAULT_PORTS = { 'http' => 80, 'https' => 443, 'coffee' => 80 }
|
2012-01-30 08:57:03 +00:00
|
|
|
default_reaction :deny
|
2016-05-29 20:25:07 +00:00
|
|
|
default_options :allow_if => nil
|
2012-01-30 08:57:03 +00:00
|
|
|
|
2012-12-12 10:03:07 +00:00
|
|
|
def base_url(env)
|
|
|
|
request = Rack::Request.new(env)
|
|
|
|
port = ":#{request.port}" unless request.port == DEFAULT_PORTS[request.scheme]
|
|
|
|
"#{request.scheme}://#{request.host}#{port}"
|
|
|
|
end
|
2012-01-30 08:57:03 +00:00
|
|
|
|
2012-12-12 10:03:07 +00:00
|
|
|
def accepts?(env)
|
|
|
|
return true if safe? env
|
|
|
|
return true unless origin = env['HTTP_ORIGIN']
|
|
|
|
return true if base_url(env) == origin
|
2016-05-29 20:25:07 +00:00
|
|
|
return true if options[:allow_if] && options[:allow_if].call(env)
|
2020-07-11 16:01:34 +00:00
|
|
|
|
|
|
|
if options.key? :origin_whitelist
|
2020-09-18 02:11:43 +00:00
|
|
|
warn env, "Rack::Protection origin_whitelist option is deprecated and will be removed, " \
|
2020-07-12 13:27:50 +00:00
|
|
|
"use permitted_origins instead.\n"
|
2020-07-11 16:01:34 +00:00
|
|
|
end
|
|
|
|
|
2020-07-11 16:29:05 +00:00
|
|
|
permitted_origins = options[:permitted_origins] || options[:origin_whitelist]
|
2020-07-11 16:01:34 +00:00
|
|
|
Array(permitted_origins).include? origin
|
2012-01-30 08:57:03 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|