Class: Rack::LibInjection

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/libinjection.rb

Defined Under Namespace

Classes: Attack, Config

Constant Summary collapse

DEFAULT_SCAN =
%i[params].freeze
DEFAULT_THREATS =
%i[sqli xss].freeze
DEFAULT_IGNORE_PARAMS =
%w[authenticity_token].freeze
DEFAULT_IGNORE_HEADERS =
%w[
  accept
  accept-encoding
  accept-language
  cache-control
  connection
  content-length
  content-type
  host
  pragma
  sec-ch-ua
  sec-ch-ua-mobile
  sec-ch-ua-platform
  sec-fetch-dest
  sec-fetch-mode
  sec-fetch-site
  upgrade-insecure-requests
].freeze
DEFAULT_MAX_VALUE_BYTES =
8 * 1024
DEFAULT_MAX_DEPTH =
8
DEFAULT_PATH_DECODE_DEPTH =
2
ATTACK_ENV_KEY =
"rack.libinjection.attacks"
EVENT_NAME =
"rack.libinjection.attack"
ERROR_EVENT =
"rack.libinjection.error"
SKIPPED_EVENT =
"rack.libinjection.skipped"
VALID_MODES =
%i[report block off].freeze
VALID_SCAN =
%i[query params path headers cookies].freeze
VALID_THREATS =
%i[sqli xss].freeze
VALID_PARSER_ERRORS =
%i[auto report block raise].freeze
VALID_NOTIFIER_ERRORS =
%i[ignore raise].freeze
VALID_SKIPPED_INPUTS =
%i[auto report block allow].freeze
MAX_PATH_DECODE_DEPTH =
32
PARAMETER_ERRORS =
[
  defined?(::Rack::QueryParser::ParameterTypeError) && ::Rack::QueryParser::ParameterTypeError,
  defined?(::Rack::QueryParser::InvalidParameterError) && ::Rack::QueryParser::InvalidParameterError,
  defined?(::Rack::QueryParser::ParamsTooDeepError) && ::Rack::QueryParser::ParamsTooDeepError,
  defined?(::Rack::Utils::ParameterTypeError) && ::Rack::Utils::ParameterTypeError,
  defined?(::Rack::Utils::InvalidParameterError) && ::Rack::Utils::InvalidParameterError,
  defined?(::Rack::Utils::ParamsTooDeepError) && ::Rack::Utils::ParamsTooDeepError
].select { |value| value.is_a?(Class) }.uniq.freeze
FORBIDDEN_HEADERS =
{ "content-type" => "text/plain; charset=utf-8" }.freeze
FORBIDDEN_BODY =
["Forbidden\n"].freeze
NOOP_NOTIFIER =
->(_event, _payload) {}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, **options) ⇒ LibInjection

Returns a new instance of LibInjection.



262
263
264
265
# File 'lib/rack/libinjection.rb', line 262

def initialize(app, **options)
  @app    = app
  @config = Config.build(**options)
end

Instance Attribute Details

#appObject (readonly)

Returns the value of attribute app.



260
261
262
# File 'lib/rack/libinjection.rb', line 260

def app
  @app
end

#configObject (readonly)

Returns the value of attribute config.



260
261
262
# File 'lib/rack/libinjection.rb', line 260

def config
  @config
end

Instance Method Details

#call(env) ⇒ Object



277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/rack/libinjection.rb', line 277

def call(env)
  return app.call(env) if mode == :off

  context = nil
  attacks = nil

  if config.env_only_scan?
    context = env
    attacks = collect_attacks_from_env(env)
  else
    context = ::Rack::Request.new(env)
    attacks = collect_attacks(context)
  end

  env[ATTACK_ENV_KEY] = attacks

  if attacks.any?
    notify_attacks(context, attacks)
    return forbidden_response if mode == :block
  end

  app.call(env)
rescue ParserBlocked
  env[ATTACK_ENV_KEY] = []
  forbidden_response
end

#ignore_paramsObject



270
# File 'lib/rack/libinjection.rb', line 270

def ignore_params   = config.ignore_params

#max_depthObject



272
# File 'lib/rack/libinjection.rb', line 272

def max_depth       = config.max_depth

#max_value_bytesObject



271
# File 'lib/rack/libinjection.rb', line 271

def max_value_bytes = config.max_value_bytes

#modeObject



267
# File 'lib/rack/libinjection.rb', line 267

def mode            = config.mode

#notifierObject



275
# File 'lib/rack/libinjection.rb', line 275

def notifier        = config.notifier

#parser_errorsObject



274
# File 'lib/rack/libinjection.rb', line 274

def parser_errors   = config.parser_errors

#path_decode_depthObject



273
# File 'lib/rack/libinjection.rb', line 273

def path_decode_depth = config.path_decode_depth

#scanObject



268
# File 'lib/rack/libinjection.rb', line 268

def scan            = config.scan

#threatsObject



269
# File 'lib/rack/libinjection.rb', line 269

def threats         = config.threats