Class: Rack::Protection::Base
| Relationships & Source Files | |
| Extension / Inclusion / Inheritance Descendants | |
|
Subclasses:
|
|
| Inherits: | Object |
| Defined in: | rack-protection/lib/rack/protection/base.rb |
Overview
Base class for middlewares provided by rack-protection.
Options
These may be given to any subclass, however they may affect different subclasses differently.
[:reaction] - name of a method of the class that will be used to respond when the middleware rejects the response. Default behavior is to use #default_reaction. [:logging] - if true, debug and warning statements are sent to the logger. [:message] - if set, this is the message sent when a request is rejected via deny. See DEFAULT_OPTIONS. [:session_key] - string to use as the key into env where the current session is stored. See DEFAULT_OPTIONS. [:status] - HTTP status to use when a request is rejected via deny. See DEFAULT_OPTIONS. [:report_key] - key set in env if the request has been denied and :reaction is set to :report (see #report). See DEFAULT_OPTIONS. [:html_types] - Array of strings containing content types that are consider HTML for the purposes of this gem. See DEFAULT_OPTIONS.
Constant Summary
-
DEFAULT_OPTIONS =
# File 'rack-protection/lib/rack/protection/base.rb', line 33{ reaction: :default_reaction, logging: true, message: 'Forbidden', encryptor: Digest::SHA1, session_key: 'rack.session', status: 403, allow_empty_referrer: true, report_key: 'protection.failed', html_types: %w[text/html application/xhtml text/xml application/xml] }
Class Method Summary
-
.default_options(options)
Used by subclasses to declare default values for options they require.
-
.default_reaction(reaction)
Used by subclasses to declare default reaction when a request is rejected.
- .new(app, options = {}) ⇒ Base constructor
Instance Attribute Summary
Instance Method Summary
- #accepts?(env) ⇒ Boolean
- #call(env)
- #debug(env, message)
- #default_options
-
#default_reaction(env)
Alias for #deny.
-
#deny(env)
(also: #default_reaction, #react)
Deny the request.
- #drop_session(env)
- #encrypt(value)
- #html?(headers) ⇒ Boolean
- #instrument(env)
- #origin(env)
- #random_string(secure = defined? SecureRandom))
- #react(env)
- #referrer(env)
-
#report(env)
When used as a reaction (with option reaction: :report), any rejected request will be allowed through, and a warning is omitted (note that warnings will not be shown if the :logging option has been set to false).
- #safe?(env) ⇒ Boolean
- #secure_compare(a, b)
- #session(env)
- #session?(env) ⇒ Boolean
- #warn(env, message)
Constructor Details
.new(app, options = {}) ⇒ Base
Class Method Details
.default_options(options)
Used by subclasses to declare default values for options they require. These defaults are merged onto the DEFAULT_OPTIONS provided by this class.
# File 'rack-protection/lib/rack/protection/base.rb', line 46
def self.() define_method(:) { super().merge() } end
.default_reaction(reaction)
Used by subclasses to declare default reaction when a request is rejected. This replaces the default provided by this class. See #default_reaction.
# File 'rack-protection/lib/rack/protection/base.rb', line 53
def self.default_reaction(reaction) alias_method(:default_reaction, reaction) end
Instance Attribute Details
#app (readonly)
[ GitHub ]# File 'rack-protection/lib/rack/protection/base.rb', line 42
attr_reader :app, :
#options (readonly)
[ GitHub ]# File 'rack-protection/lib/rack/protection/base.rb', line 42
attr_reader :app, :
Instance Method Details
#accepts?(env) ⇒ Boolean
# File 'rack-protection/lib/rack/protection/base.rb', line 70
def accepts?(env) raise NotImplementedError, "#{self.class} implementation pending" end
#call(env)
[ GitHub ]# File 'rack-protection/lib/rack/protection/base.rb', line 74
def call(env) unless accepts? env instrument env result = react env end result or app.call(env) end
#debug(env, message)
[ GitHub ]# File 'rack-protection/lib/rack/protection/base.rb', line 87
def debug(env, ) return unless [:logging] l = [:logger] || env['rack.logger'] || ::Logger.new(env['rack.errors']) l.debug() end
#default_options
[ GitHub ]# File 'rack-protection/lib/rack/protection/base.rb', line 57
def DEFAULT_OPTIONS end
#default_reaction(env)
Alias for #deny.
# File 'rack-protection/lib/rack/protection/base.rb', line 170
alias default_reaction deny
#deny(env) Also known as: #default_reaction, #react
Deny the request. Sends a content type of "text/plain" using the status and message set in the options.
# File 'rack-protection/lib/rack/protection/base.rb', line 110
def deny(env) warn env, "attack prevented by #{self.class}" [[:status], { 'content-type' => 'text/plain' }, [[:]]] end
#drop_session(env)
[ GitHub ]#encrypt(value)
[ GitHub ]# File 'rack-protection/lib/rack/protection/base.rb', line 162
def encrypt(value) [:encryptor].hexdigest value.to_s end
#html?(headers) ⇒ Boolean
# File 'rack-protection/lib/rack/protection/base.rb', line 172
def html?(headers) return false unless (header = headers.detect { |k, _v| k.downcase == 'content-type' }) [:html_types].include? header.last[%r{^\w+/\w+}] end
#instrument(env)
[ GitHub ]# File 'rack-protection/lib/rack/protection/base.rb', line 101
def instrument(env) return unless (i = [:instrumenter]) env['rack.protection.attack'] = self.class.name.split('::').last.downcase i.instrument('rack.protection', env) end
#origin(env)
[ GitHub ]# File 'rack-protection/lib/rack/protection/base.rb', line 152
def origin(env) env['HTTP_ORIGIN'] || env['HTTP_X_ORIGIN'] end
#random_string(secure = defined? SecureRandom))
[ GitHub ]# File 'rack-protection/lib/rack/protection/base.rb', line 156
def random_string(secure = defined? SecureRandom) secure ? SecureRandom.hex(16) : '%032x' % rand((2**128) - 1) rescue NotImplementedError random_string false end
#react(env)
[ GitHub ]# File 'rack-protection/lib/rack/protection/base.rb', line 82
def react(env) result = send([:reaction], env) result if (Array === result) && (result.size == 3) end
#referrer(env)
[ GitHub ]# File 'rack-protection/lib/rack/protection/base.rb', line 144
def referrer(env) ref = env['HTTP_REFERER'].to_s return if ![:allow_empty_referrer] && ref.empty? URI.parse(ref).host || Request.new(env).host rescue URI::InvalidURIError end
#report(env)
When used as a reaction (with option reaction: :report), any rejected request will be allowed through, and a warning is omitted (note that warnings will not be shown if the :logging option has been set to false).
# File 'rack-protection/lib/rack/protection/base.rb', line 119
def report(env) warn env, "attack reported by #{self.class}" env[[:report_key]] = true end
#safe?(env) ⇒ Boolean
# File 'rack-protection/lib/rack/protection/base.rb', line 66
def safe?(env) %w[GET HEAD OPTIONS TRACE].include? env['REQUEST_METHOD'] end
#secure_compare(a, b)
[ GitHub ]# File 'rack-protection/lib/rack/protection/base.rb', line 166
def secure_compare(a, b) Rack::Utils.secure_compare(a.to_s, b.to_s) end
#session(env)
[ GitHub ]# File 'rack-protection/lib/rack/protection/base.rb', line 128
def session(env) return env[[:session_key]] if session? env raise "you need to set up a session middleware *before* #{self.class}" end
#session?(env) ⇒ Boolean
# File 'rack-protection/lib/rack/protection/base.rb', line 124
def session?(env) env.include? [:session_key] end
#warn(env, message)
[ GitHub ]# File 'rack-protection/lib/rack/protection/base.rb', line 94
def warn(env, ) return unless [:logging] l = [:logger] || env['rack.logger'] || ::Logger.new(env['rack.errors']) l.warn() end