Class: Contrast::Agent::Protect::Rule::Deserialization

Inherits:
Base
  • Object
show all
Defined in:
lib/contrast/agent/protect/rule/deserialization.rb

Overview

This class handles our implementation of the Untrusted Deserialization Protect rule.

Constant Summary collapse

NAME =

The TeamServer recognized name of this rule

'untrusted-deserialization'
BLOCK_MESSAGE =

The rule specific reason for raising a security exception.

'Untrusted Deserialization rule triggered. Deserialization blocked.'
ERB_GADGETS =

Gadgets that map to ERB modules

%w[
  object:ERB
].cs__freeze
ACTION_DISPATCH_GADGETS =

Gadgets that map to ActionDispatch modules

%w[
  object:ActionDispatch::Routing::RouteSet::NamedRouteCollection
].cs__freeze
AREL_GADGETS =

Gadgets that map to Arel Modules

%w[
  string:Arel::Nodes::SqlLiteral
  object:Arel::Nodes
].cs__freeze
ERB =

Used to indicate to TeamServer the gadget is an ERB module

'ERB'
DISPATCH =

Used to indicate to TeamServer the gadget is an ActionDispatch module

'ActionDispatch'
AREL =

Used to indicate to TeamServer the gadget is an Arel module

'Arel'

Constants inherited from Base

Base::BLOCKING_MODES, Base::OFF, Base::POSTFILTER_MODES, Base::STACK_COLLECTION_RESULTS, Base::UNKNOWN_USER_INPUT

Instance Attribute Summary

Attributes inherited from Base

#mode

Instance Method Summary collapse

Methods inherited from Base

#append_to_activity, #build_attack_with_match, #build_attack_without_match, #enabled?, #excluded?, #initialize, #postfilter, #prefilter, #stream_safe?

Methods included from Components::Interface

included

Constructor Details

This class inherits a constructor from Contrast::Agent::Protect::Rule::Base

Instance Method Details

#block_messageString

Return the specific blocking message for this rule.

Returns:

  • (String)

    the reason for the raised security exception.



51
52
53
# File 'lib/contrast/agent/protect/rule/deserialization.rb', line 51

def block_message
  BLOCK_MESSAGE
end

#check_command_scope(gadget_command) ⇒ Object

Determine if the issued command was called while we’re deserializing. If we are, treat this as an attack.

Parameters:

  • gadget_command (String)

    the command being executed during the deserialization call.

Raises:



94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/contrast/agent/protect/rule/deserialization.rb', line 94

def check_command_scope gadget_command
  # If we're within 'deserialization scope', then we've got a
  # deserialization method in our call stack.
  return unless in_deserialization_scope?

  context = Contrast::Agent::REQUEST_TRACKER.current
  kwargs = { COMMAND_SCOPE: true }
  ia_result = build_evaluation(gadget_command)
  result = build_attack_with_match(context, ia_result, nil, gadget_command, **kwargs)
  append_to_activity(context, result)
  raise Contrast::SecurityException.new(self, BLOCK_MESSAGE) if blocked?
end

#infilter(context, serialized_input) ⇒ Object

Determine if the input being deserialized is an attack and take appropriate actions.

Parameters:

Raises:



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/contrast/agent/protect/rule/deserialization.rb', line 72

def infilter context, serialized_input
  return unless infilter?(context)

  gadget = find_gadget(serialized_input)
  # If there isn't a gadget, this isn't an attack, so we have nothing
  # to do here. Let the application carry on business as usual.
  return unless gadget

  ia_result = build_evaluation(serialized_input)
  kwargs = { GADGET_TYPE: gadget }
  result = build_attack_with_match(context, ia_result, nil, serialized_input, **kwargs)
  append_to_activity(context, result)

  raise Contrast::SecurityException.new(self, block_message) if blocked?
end

#infilter?(_context) ⇒ Boolean

Per the spec, this rule applies regardless of input. Only the mode of the rule and code exclusions apply at this point.

Returns:

  • (Boolean)

    should the rule apply to this call.



58
59
60
61
62
63
# File 'lib/contrast/agent/protect/rule/deserialization.rb', line 58

def infilter? _context
  return false unless enabled?
  return false if protect_excluded_by_code?

  true
end

#nameString

Return the TeamServer understood id / name of this rule.

Returns:

  • (String)

    the TeamServer understood id / name of this rule.



45
46
47
# File 'lib/contrast/agent/protect/rule/deserialization.rb', line 45

def name
  NAME
end