123456789_123456789_123456789_123456789_123456789_

Class: Rack::Protection::Base

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(app, options = {}) ⇒ Base

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 35

def initialize(app, options = {})
  @app = app
  @options = default_options.merge(options)
end

Class Method Details

.default_options(options)

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 23

def self.default_options(options)
  define_method(:default_options) { super().merge(options) }
end

.default_reaction(reaction)

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 27

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 21

attr_reader :app, :options

#options (readonly)

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 21

attr_reader :app, :options

Instance Method Details

#accepts?(env) ⇒ Boolean

Raises:

  • (NotImplementedError)
[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 44

def accepts?(env)
  raise NotImplementedError, "#{self.class} implementation pending"
end

#call(env)

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 48

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 61

def debug(env, message)
  return unless options[:logging]

  l = options[:logger] || env['rack.logger'] || ::Logger.new(env['rack.errors'])
  l.debug(message)
end

#default_options

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 31

def default_options
  DEFAULT_OPTIONS
end

#default_reaction(env)

Alias for #deny.

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 138

alias default_reaction deny

#deny(env) Also known as: #default_reaction, #react

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 82

def deny(env)
  warn env, "attack prevented by #{self.class}"
  [options[:status], { 'content-type' => 'text/plain' }, [options[:message]]]
end

#drop_session(env)

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 102

def drop_session(env)
  return unless session? env

  session(env).clear

  return if ["1", "true"].include?(ENV["RACK_PROTECTION_SILENCE_DROP_SESSION_WARNING"])

  warn env, "session dropped by #{self.class}"
end

#encrypt(value)

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 130

def encrypt(value)
  options[:encryptor].hexdigest value.to_s
end

#html?(headers) ⇒ Boolean

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 140

def html?(headers)
  return false unless (header = headers.detect { |k, _v| k.downcase == 'content-type' })

  options[:html_types].include? header.last[%r{^\w+/\w+}]
end

#instrument(env)

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 75

def instrument(env)
  return unless (i = options[: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 120

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 124

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 56

def react(env)
  result = send(options[:reaction], env)
  result if (Array === result) && (result.size == 3)
end

#referrer(env)

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 112

def referrer(env)
  ref = env['HTTP_REFERER'].to_s
  return if !options[:allow_empty_referrer] && ref.empty?

  URI.parse(ref).host || Request.new(env).host
rescue URI::InvalidURIError
end

#report(env)

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 87

def report(env)
  warn env, "attack reported by #{self.class}"
  env[options[:report_key]] = true
end

#safe?(env) ⇒ Boolean

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 40

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 134

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 96

def session(env)
  return env[options[:session_key]] if session? env

  raise "you need to set up a session middleware *before* #{self.class}"
end

#session?(env) ⇒ Boolean

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 92

def session?(env)
  env.include? options[:session_key]
end

#warn(env, message)

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/base.rb', line 68

def warn(env, message)
  return unless options[:logging]

  l = options[:logger] || env['rack.logger'] || ::Logger.new(env['rack.errors'])
  l.warn(message)
end