contrast-agent 4.6.0 → 4.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (190) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -1
  3. data/.gitmodules +1 -1
  4. data/.simplecov +1 -0
  5. data/Rakefile +1 -2
  6. data/ext/build_funchook.rb +3 -3
  7. data/ext/extconf_common.rb +1 -5
  8. data/lib/contrast.rb +24 -14
  9. data/lib/contrast/agent/assess.rb +1 -1
  10. data/lib/contrast/agent/assess/contrast_event.rb +1 -4
  11. data/lib/contrast/agent/assess/contrast_object.rb +2 -2
  12. data/lib/contrast/agent/assess/events/event_factory.rb +2 -1
  13. data/lib/contrast/agent/assess/finalizers/hash.rb +2 -4
  14. data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +6 -3
  15. data/lib/contrast/agent/assess/policy/patcher.rb +16 -21
  16. data/lib/contrast/agent/assess/policy/policy.rb +1 -1
  17. data/lib/contrast/agent/assess/policy/policy_node.rb +25 -33
  18. data/lib/contrast/agent/assess/policy/policy_scanner.rb +3 -5
  19. data/lib/contrast/agent/assess/policy/preshift.rb +7 -5
  20. data/lib/contrast/agent/assess/policy/propagation_method.rb +10 -19
  21. data/lib/contrast/agent/assess/policy/propagation_node.rb +19 -8
  22. data/lib/contrast/agent/assess/policy/propagator.rb +1 -0
  23. data/lib/contrast/agent/assess/policy/propagator/center.rb +2 -1
  24. data/lib/contrast/agent/assess/policy/propagator/database_write.rb +3 -6
  25. data/lib/contrast/agent/assess/policy/propagator/insert.rb +3 -1
  26. data/lib/contrast/agent/assess/policy/propagator/match_data.rb +2 -1
  27. data/lib/contrast/agent/assess/policy/propagator/rack_protection.rb +73 -0
  28. data/lib/contrast/agent/assess/policy/propagator/select.rb +2 -12
  29. data/lib/contrast/agent/assess/policy/propagator/split.rb +12 -13
  30. data/lib/contrast/agent/assess/policy/propagator/substitution.rb +3 -10
  31. data/lib/contrast/agent/assess/policy/propagator/trim.rb +3 -15
  32. data/lib/contrast/agent/assess/policy/rewriter_patch.rb +13 -10
  33. data/lib/contrast/agent/assess/policy/source_method.rb +12 -12
  34. data/lib/contrast/agent/assess/policy/source_validation/source_validation.rb +1 -3
  35. data/lib/contrast/agent/assess/policy/trigger/reflected_xss.rb +5 -1
  36. data/lib/contrast/agent/assess/policy/trigger/xpath.rb +0 -3
  37. data/lib/contrast/agent/assess/policy/trigger_method.rb +8 -18
  38. data/lib/contrast/agent/assess/policy/trigger_node.rb +3 -2
  39. data/lib/contrast/agent/assess/policy/trigger_validation/redos_validator.rb +4 -3
  40. data/lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb +1 -2
  41. data/lib/contrast/agent/assess/policy/trigger_validation/xss_validator.rb +1 -8
  42. data/lib/contrast/agent/assess/property/evented.rb +8 -5
  43. data/lib/contrast/agent/assess/rule/provider/hardcoded_key.rb +11 -5
  44. data/lib/contrast/agent/assess/rule/provider/hardcoded_password.rb +4 -1
  45. data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +7 -9
  46. data/lib/contrast/agent/at_exit_hook.rb +3 -3
  47. data/lib/contrast/agent/class_reopener.rb +9 -6
  48. data/lib/contrast/agent/disable_reaction.rb +4 -7
  49. data/lib/contrast/agent/exclusion_matcher.rb +7 -14
  50. data/lib/contrast/agent/inventory/dependencies.rb +2 -0
  51. data/lib/contrast/agent/inventory/dependency_analysis.rb +2 -6
  52. data/lib/contrast/agent/inventory/dependency_usage_analysis.rb +3 -5
  53. data/lib/contrast/agent/inventory/policy/datastores.rb +3 -4
  54. data/lib/contrast/agent/inventory/policy/policy.rb +1 -1
  55. data/lib/contrast/agent/middleware.rb +17 -18
  56. data/lib/contrast/agent/module_data.rb +3 -3
  57. data/lib/contrast/agent/patching/policy/after_load_patch.rb +3 -3
  58. data/lib/contrast/agent/patching/policy/after_load_patcher.rb +9 -9
  59. data/lib/contrast/agent/patching/policy/method_policy.rb +6 -2
  60. data/lib/contrast/agent/patching/policy/module_policy.rb +14 -7
  61. data/lib/contrast/agent/patching/policy/patch.rb +20 -25
  62. data/lib/contrast/agent/patching/policy/patch_status.rb +6 -7
  63. data/lib/contrast/agent/patching/policy/patcher.rb +21 -18
  64. data/lib/contrast/agent/patching/policy/policy.rb +2 -4
  65. data/lib/contrast/agent/patching/policy/policy_node.rb +16 -7
  66. data/lib/contrast/agent/patching/policy/trigger_node.rb +21 -8
  67. data/lib/contrast/agent/protect/policy/applies_command_injection_rule.rb +1 -1
  68. data/lib/contrast/agent/protect/policy/applies_deserialization_rule.rb +1 -1
  69. data/lib/contrast/agent/protect/policy/applies_no_sqli_rule.rb +1 -1
  70. data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +2 -3
  71. data/lib/contrast/agent/protect/policy/applies_sqli_rule.rb +1 -1
  72. data/lib/contrast/agent/protect/policy/applies_xxe_rule.rb +5 -9
  73. data/lib/contrast/agent/protect/policy/policy.rb +1 -1
  74. data/lib/contrast/agent/protect/policy/rule_applicator.rb +7 -9
  75. data/lib/contrast/agent/protect/rule/base.rb +20 -23
  76. data/lib/contrast/agent/protect/rule/base_service.rb +9 -5
  77. data/lib/contrast/agent/protect/rule/cmd_injection.rb +18 -23
  78. data/lib/contrast/agent/protect/rule/deserialization.rb +6 -13
  79. data/lib/contrast/agent/protect/rule/http_method_tampering.rb +3 -14
  80. data/lib/contrast/agent/protect/rule/no_sqli.rb +6 -2
  81. data/lib/contrast/agent/protect/rule/no_sqli/mongo_no_sql_scanner.rb +1 -3
  82. data/lib/contrast/agent/protect/rule/path_traversal.rb +6 -10
  83. data/lib/contrast/agent/protect/rule/sqli.rb +1 -1
  84. data/lib/contrast/agent/protect/rule/unsafe_file_upload.rb +1 -1
  85. data/lib/contrast/agent/protect/rule/xss.rb +1 -1
  86. data/lib/contrast/agent/protect/rule/xxe.rb +5 -12
  87. data/lib/contrast/agent/protect/rule/xxe/entity_wrapper.rb +1 -2
  88. data/lib/contrast/agent/reaction_processor.rb +13 -13
  89. data/lib/contrast/agent/request.rb +27 -26
  90. data/lib/contrast/agent/request_context.rb +17 -22
  91. data/lib/contrast/agent/request_handler.rb +5 -3
  92. data/lib/contrast/agent/response.rb +2 -3
  93. data/lib/contrast/agent/rewriter.rb +9 -6
  94. data/lib/contrast/agent/rule_set.rb +5 -4
  95. data/lib/contrast/agent/service_heartbeat.rb +4 -6
  96. data/lib/contrast/agent/static_analysis.rb +6 -5
  97. data/lib/contrast/agent/thread.rb +2 -4
  98. data/lib/contrast/agent/thread_watcher.rb +3 -4
  99. data/lib/contrast/agent/tracepoint_hook.rb +5 -5
  100. data/lib/contrast/agent/version.rb +1 -1
  101. data/lib/contrast/api/communication/messaging_queue.rb +4 -5
  102. data/lib/contrast/api/communication/response_processor.rb +11 -13
  103. data/lib/contrast/api/communication/service_lifecycle.rb +9 -6
  104. data/lib/contrast/api/communication/socket_client.rb +22 -31
  105. data/lib/contrast/api/communication/speedracer.rb +8 -13
  106. data/lib/contrast/api/decorators/address.rb +2 -3
  107. data/lib/contrast/api/decorators/agent_startup.rb +7 -9
  108. data/lib/contrast/api/decorators/application_startup.rb +12 -10
  109. data/lib/contrast/api/decorators/application_update.rb +0 -4
  110. data/lib/contrast/api/decorators/http_request.rb +3 -7
  111. data/lib/contrast/api/decorators/instrumentation_mode.rb +3 -5
  112. data/lib/contrast/api/decorators/library.rb +8 -6
  113. data/lib/contrast/api/decorators/message.rb +9 -9
  114. data/lib/contrast/api/decorators/trace_event.rb +3 -1
  115. data/lib/contrast/api/decorators/trace_event_object.rb +3 -6
  116. data/lib/contrast/api/decorators/trace_taint_range_tags.rb +1 -6
  117. data/lib/contrast/components/agent.rb +17 -17
  118. data/lib/contrast/components/app_context.rb +11 -15
  119. data/lib/contrast/components/assess.rb +16 -16
  120. data/lib/contrast/components/base.rb +40 -0
  121. data/lib/contrast/components/config.rb +2 -3
  122. data/lib/contrast/components/contrast_service.rb +12 -18
  123. data/lib/contrast/components/heap_dump.rb +5 -4
  124. data/lib/contrast/components/inventory.rb +2 -7
  125. data/lib/contrast/components/logger.rb +1 -2
  126. data/lib/contrast/components/protect.rb +10 -13
  127. data/lib/contrast/components/sampling.rb +13 -7
  128. data/lib/contrast/components/scope.rb +0 -4
  129. data/lib/contrast/components/settings.rb +5 -7
  130. data/lib/contrast/config/assess_rules_configuration.rb +1 -3
  131. data/lib/contrast/config/base_configuration.rb +4 -5
  132. data/lib/contrast/config/exception_configuration.rb +1 -5
  133. data/lib/contrast/config/heap_dump_configuration.rb +12 -6
  134. data/lib/contrast/config/logger_configuration.rb +1 -5
  135. data/lib/contrast/configuration.rb +6 -18
  136. data/lib/contrast/extension/assess/array.rb +3 -10
  137. data/lib/contrast/extension/assess/erb.rb +1 -7
  138. data/lib/contrast/extension/assess/eval_trigger.rb +4 -9
  139. data/lib/contrast/extension/assess/exec_trigger.rb +3 -9
  140. data/lib/contrast/extension/assess/fiber.rb +8 -17
  141. data/lib/contrast/extension/assess/hash.rb +3 -3
  142. data/lib/contrast/extension/assess/kernel.rb +4 -13
  143. data/lib/contrast/extension/assess/marshal.rb +6 -10
  144. data/lib/contrast/extension/assess/regexp.rb +6 -10
  145. data/lib/contrast/extension/assess/string.rb +8 -6
  146. data/lib/contrast/extension/kernel.rb +2 -2
  147. data/lib/contrast/extension/protect/kernel.rb +0 -5
  148. data/lib/contrast/framework/manager.rb +3 -5
  149. data/lib/contrast/framework/rack/patch/session_cookie.rb +11 -24
  150. data/lib/contrast/framework/rack/patch/support.rb +6 -4
  151. data/lib/contrast/framework/rails/patch/assess_configuration.rb +12 -9
  152. data/lib/contrast/framework/rails/patch/support.rb +41 -35
  153. data/lib/contrast/framework/rails/railtie.rb +34 -0
  154. data/lib/contrast/framework/rails/rewrite/action_controller_railties_helper_inherited.rb +4 -1
  155. data/lib/contrast/framework/rails/rewrite/active_record_attribute_methods_read.rb +2 -0
  156. data/lib/contrast/framework/rails/rewrite/active_record_named.rb +5 -4
  157. data/lib/contrast/framework/rails/rewrite/active_record_time_zone_inherited.rb +2 -0
  158. data/lib/contrast/framework/rails/support.rb +2 -2
  159. data/lib/contrast/framework/sinatra/support.rb +3 -1
  160. data/lib/contrast/funchook/funchook.rb +5 -8
  161. data/lib/contrast/logger/application.rb +13 -15
  162. data/lib/contrast/logger/format.rb +2 -5
  163. data/lib/contrast/logger/log.rb +26 -9
  164. data/lib/contrast/logger/request.rb +1 -6
  165. data/lib/contrast/security_exception.rb +1 -1
  166. data/lib/contrast/tasks/config.rb +0 -1
  167. data/lib/contrast/tasks/service.rb +6 -7
  168. data/lib/contrast/utils/assess/sampling_util.rb +2 -3
  169. data/lib/contrast/utils/assess/tracking_util.rb +3 -6
  170. data/lib/contrast/utils/class_util.rb +0 -8
  171. data/lib/contrast/utils/hash_digest.rb +2 -5
  172. data/lib/contrast/utils/heap_dump_util.rb +5 -3
  173. data/lib/contrast/utils/invalid_configuration_util.rb +4 -3
  174. data/lib/contrast/utils/inventory_util.rb +2 -3
  175. data/lib/contrast/utils/io_util.rb +3 -5
  176. data/lib/contrast/utils/job_servers_running.rb +13 -7
  177. data/lib/contrast/utils/os.rb +4 -4
  178. data/lib/contrast/utils/ruby_ast_rewriter.rb +2 -1
  179. data/lib/contrast/utils/string_utils.rb +2 -3
  180. data/lib/contrast/utils/tag_util.rb +25 -19
  181. data/resources/assess/policy.json +55 -0
  182. data/ruby-agent.gemspec +17 -16
  183. data/service_executables/VERSION +1 -1
  184. data/service_executables/linux/contrast-service +0 -0
  185. data/service_executables/mac/contrast-service +0 -0
  186. data/sonar-project.properties +9 -0
  187. metadata +61 -46
  188. data/lib/contrast/agent/railtie.rb +0 -31
  189. data/lib/contrast/components/interface.rb +0 -195
  190. data/lib/contrast/delegators/input_analysis.rb +0 -12
@@ -12,7 +12,7 @@ module Contrast
12
12
  NAME = 'nosql-injection'
13
13
  BLOCK_MESSAGE = 'NoSQLi rule triggered. Response blocked.'
14
14
 
15
- def name
15
+ def rule_name
16
16
  NAME
17
17
  end
18
18
 
@@ -32,7 +32,11 @@ module Contrast
32
32
  end
33
33
 
34
34
  def build_attack_with_match context, input_analysis_result, result, query_string, **kwargs
35
- return result if mode == Contrast::Api::Settings::ProtectionRule::Mode::NO_ACTION || mode == Contrast::Api::Settings::ProtectionRule::Mode::PERMIT
35
+ if mode == Contrast::Api::Settings::ProtectionRule::Mode::NO_ACTION ||
36
+ mode == Contrast::Api::Settings::ProtectionRule::Mode::PERMIT
37
+
38
+ return result
39
+ end
36
40
 
37
41
  attack_string = input_analysis_result.value
38
42
  regexp = Regexp.new(Regexp.escape(attack_string), Regexp::IGNORECASE)
@@ -14,9 +14,7 @@ module Contrast
14
14
  # Is the current & next character '//' or are the current and
15
15
  # subsequent characters '<--' ?
16
16
  def start_line_comment? char, index, query
17
- if char == Contrast::Utils::ObjectShare::SLASH &&
18
- query[index + 1] == Contrast::Utils::ObjectShare::SLASH
19
-
17
+ if char == Contrast::Utils::ObjectShare::SLASH && query[index + 1] == Contrast::Utils::ObjectShare::SLASH
20
18
  return true
21
19
  end
22
20
 
@@ -2,7 +2,6 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'contrast/agent/protect/rule/base_service'
5
- require 'contrast/components/interface'
6
5
  require 'contrast/utils/stack_trace_utils'
7
6
 
8
7
  module Contrast
@@ -12,9 +11,6 @@ module Contrast
12
11
  # This class handles our implementation of the Path Traversal
13
12
  # Protect rule.
14
13
  class PathTraversal < Contrast::Agent::Protect::Rule::BaseService
15
- include Contrast::Components::Interface
16
- access_component :agent, :analysis
17
-
18
14
  NAME = 'path-traversal'
19
15
  SYSTEM_PATHS = %w[
20
16
  /proc/self
@@ -29,7 +25,7 @@ module Contrast
29
25
  /windows/repair/
30
26
  ].cs__freeze
31
27
 
32
- def name
28
+ def rule_name
33
29
  NAME
34
30
  end
35
31
 
@@ -42,9 +38,8 @@ module Contrast
42
38
  append_to_activity(context, result)
43
39
  return unless blocked?
44
40
 
45
- raise Contrast::SecurityException.new(
46
- self,
47
- "Path Traversal rule triggered. Call to File.#{ method } blocked.")
41
+ raise Contrast::SecurityException.new(self,
42
+ "Path Traversal rule triggered. Call to File.#{ method } blocked.")
48
43
  end
49
44
 
50
45
  protected
@@ -97,7 +92,7 @@ module Contrast
97
92
  end
98
93
 
99
94
  def custom_code_access_sysfile_enabled?
100
- PROTECT.report_custom_code_sysfile_access?
95
+ ::Contrast::PROTECT.report_custom_code_sysfile_access?
101
96
  end
102
97
 
103
98
  def custom_code_accessing_system_file? input
@@ -128,7 +123,8 @@ module Contrast
128
123
  # return 'NUL' in str(e) or 'null byte' in str(e) or (PY34 and 'embedded NUL character' == str(e))
129
124
  # except Exception as e:
130
125
  # return 'null byte' in str(e).lower()
131
- # return return any([bypass_markers.lower().rstrip('/') in realpath for bypass_markers in PathTraversalREPMixin.KNOWN_SECURITY_BYPASS_MARKERS])
126
+ # return return any([bypass_markers.lower().rstrip('/') in realpath for bypass_markers in
127
+ # PathTraversalREPMixin.KNOWN_SECURITY_BYPASS_MARKERS])
132
128
  false
133
129
  end
134
130
  end
@@ -13,7 +13,7 @@ module Contrast
13
13
  NAME = 'sql-injection'
14
14
  BLOCK_MESSAGE = 'SQLi rule triggered. Response blocked.'
15
15
 
16
- def name
16
+ def rule_name
17
17
  NAME
18
18
  end
19
19
 
@@ -12,7 +12,7 @@ module Contrast
12
12
  NAME = 'unsafe-file-upload'
13
13
  BLOCK_MESSAGE = 'Unsafe file upload rule triggered. Request blocked.'
14
14
 
15
- def name
15
+ def rule_name
16
16
  NAME
17
17
  end
18
18
  end
@@ -12,7 +12,7 @@ module Contrast
12
12
  NAME = 'reflected-xss'
13
13
  BLOCK_MESSAGE = 'XSS rule triggered. Response blocked.'
14
14
 
15
- def name
15
+ def rule_name
16
16
  NAME
17
17
  end
18
18
 
@@ -15,7 +15,7 @@ module Contrast
15
15
  BLOCK_MESSAGE = 'XXE rule triggered. Response blocked.'
16
16
  EXTERNAL_ENTITY_PATTERN = /<!ENTITY\s+[a-zA-Z0-f]+\s+(?:SYSTEM|PUBLIC)\s+(.*?)>/.cs__freeze
17
17
 
18
- def name
18
+ def rule_name
19
19
  NAME
20
20
  end
21
21
 
@@ -59,12 +59,7 @@ module Contrast
59
59
  return unless xxe_details
60
60
 
61
61
  ia_result = build_evaluation(xxe_details.xml)
62
- build_attack_with_match(
63
- context,
64
- ia_result,
65
- nil,
66
- nil,
67
- details: xxe_details)
62
+ build_attack_with_match(context, ia_result, nil, nil, details: xxe_details)
68
63
  end
69
64
 
70
65
  # Given an XML determined to be unsafe, build out the details of the
@@ -118,7 +113,7 @@ module Contrast
118
113
  # supplied by the attacker.
119
114
  def build_evaluation xml
120
115
  ia_result = Contrast::Api::Settings::InputAnalysisResult.new
121
- ia_result.rule_id = name
116
+ ia_result.rule_id = rule_name
122
117
  ia_result.input_type = :UNKNOWN
123
118
  ia_result.value = Contrast::Utils::StringUtils.protobuf_safe_string(xml)
124
119
  ia_result
@@ -133,10 +128,8 @@ module Contrast
133
128
 
134
129
  def build_wrapper entity_wrapper
135
130
  wrapper = Contrast::Api::Dtm::XxeWrapper.new
136
- wrapper.system_id = Contrast::Utils::StringUtils.protobuf_safe_string(
137
- entity_wrapper.system_id)
138
- wrapper.public_id = Contrast::Utils::StringUtils.protobuf_safe_string(
139
- entity_wrapper.public_id)
131
+ wrapper.system_id = Contrast::Utils::StringUtils.protobuf_safe_string(entity_wrapper.system_id)
132
+ wrapper.public_id = Contrast::Utils::StringUtils.protobuf_safe_string(entity_wrapper.public_id)
140
133
  wrapper
141
134
  end
142
135
  end
@@ -65,8 +65,7 @@ module Contrast
65
65
  return true if http && !tmp_id.end_with?(DTD_MARKER)
66
66
 
67
67
  # external if using external protocol
68
- return true if tmp_id.start_with?(FTP_START, FILE_START,
69
- JAR_START, GOPHER_START)
68
+ return true if tmp_id.start_with?(FTP_START, FILE_START, JAR_START, GOPHER_START)
70
69
 
71
70
  # external if start with path marker (/ or .)
72
71
  return true if tmp_id.start_with?(Contrast::Utils::ObjectShare::SLASH,
@@ -2,18 +2,15 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'contrast/agent/disable_reaction'
5
- require 'contrast/components/interface'
5
+ require 'contrast/components/logger'
6
6
 
7
7
  module Contrast
8
8
  module Agent
9
- # Because communication between the Agent/Service and TeamServer can only
10
- # be initiated by outbound connections from the Agent/Service, we must
11
- # provide a mechanism for the TeamServer to direct the Agent to take a
12
- # specific action. This action is referred to as a Reaction. This class is
13
- # how we handle those Reaction messages.
9
+ # Because communication between the Agent/Service and TeamServer can only be initiated by outbound connections
10
+ # from the Agent/Service, we must provide a mechanism for the TeamServer to direct the Agent to take a specific
11
+ # action. This action is referred to as a Reaction. This class is how we handle those Reaction messages.
14
12
  class ReactionProcessor
15
- include Contrast::Components::Interface
16
- access_component :logging
13
+ extend Contrast::Components::Logger::InstanceMethods
17
14
 
18
15
  # Process the given Reactions from the application settings based on what
19
16
  # TeamServer has indicated. Each Reaction will result in a log message
@@ -25,8 +22,12 @@ module Contrast
25
22
  return unless application_settings&.reactions&.any?
26
23
 
27
24
  application_settings.reactions.each do |reaction|
28
- # the enums are all uppercase, we need to downcase them before attempting to log
29
- level = reaction.log_level.nil? ? :error : reaction.log_level.name.downcase
25
+ # The enums are all uppercase, we need to downcase them before attempting to log.
26
+ level = if reaction.log_level.nil?
27
+ :error
28
+ else
29
+ reaction.log_level.name.downcase # rubocop:disable Security/Module/Name -- ruby logger builtin.
30
+ end
30
31
 
31
32
  logger.with_level(level, reaction.message) if reaction.message
32
33
 
@@ -36,9 +37,8 @@ module Contrast
36
37
  when Contrast::Api::Settings::Reaction::Operation::NOOP
37
38
  # NOOP
38
39
  else
39
- logger.warn(
40
- 'ReactionProcessor received a reaction with an unknown operation',
41
- operation: reaction.operation)
40
+ logger.warn('ReactionProcessor received a reaction with an unknown operation',
41
+ operation: reaction.operation)
42
42
  end
43
43
  end
44
44
  end
@@ -7,7 +7,8 @@ require 'timeout'
7
7
  require 'contrast/utils/object_share'
8
8
  require 'contrast/utils/string_utils'
9
9
  require 'contrast/utils/hash_digest'
10
- require 'contrast/components/interface'
10
+ require 'contrast/components/logger'
11
+ require 'contrast/components/scope'
11
12
 
12
13
  module Contrast
13
14
  module Agent
@@ -16,8 +17,8 @@ module Contrast
16
17
  # data in a format that the Agent expects, caching those transformations in
17
18
  # order to avoid repeatedly creating Strings & thrashing GC.
18
19
  class Request
19
- include Contrast::Components::Interface
20
- access_component :agent, :logging, :scope
20
+ include Contrast::Components::Logger::InstanceMethods
21
+ include Contrast::Components::Scope::InstanceMethods
21
22
 
22
23
  extend Forwardable
23
24
 
@@ -30,7 +31,8 @@ module Contrast
30
31
  attr_accessor :route, :observed_route
31
32
 
32
33
  # Delegate calls to the following methods to the attribute @rack_request
33
- def_delegators :@rack_request, :base_url, :content_type, :cookies, :env, :ip, :path, :port, :query_string, :request_method, :scheme, :url, :user_agent
34
+ def_delegators :@rack_request, :base_url, :content_type, :cookies, :env, :ip, :path, :port, :query_string,
35
+ :request_method, :scheme, :url, :user_agent
34
36
 
35
37
  def initialize rack_request
36
38
  @rack_request = rack_request
@@ -56,32 +58,28 @@ module Contrast
56
58
  end
57
59
 
58
60
  def document_type
59
- @_document_type ||= begin
60
- if /xml/i.match?(content_type) || body&.start_with?('<?xml')
61
- :XML
62
- elsif /json/i.match?(content_type) || body&.match?(/\s*[{\[]/)
63
- :JSON
64
- else
65
- :NORMAL
66
- end
67
- end
61
+ @_document_type ||= if /xml/i.match?(content_type) || body&.start_with?('<?xml')
62
+ :XML
63
+ elsif /json/i.match?(content_type) || body&.match?(/\s*[{\[]/)
64
+ :JSON
65
+ else
66
+ :NORMAL
67
+ end
68
68
  end
69
69
 
70
70
  # Header keys upcased and any underscores replaced with dashes
71
71
  def headers
72
- @_headers ||= begin
73
- with_contrast_scope do
74
- hash = {}
75
- env.each do |key, value|
76
- next unless key
77
-
78
- name = key.to_s
79
- next unless name.start_with?(Contrast::Utils::ObjectShare::HTTP_SCORE)
80
-
81
- hash[Contrast::Utils::StringUtils.normalized_key(name)] = value
82
- end
83
- hash
72
+ @_headers ||= with_contrast_scope do
73
+ hash = {}
74
+ env.each do |key, value|
75
+ next unless key
76
+
77
+ name = key.to_s
78
+ next unless name.start_with?(Contrast::Utils::ObjectShare::HTTP_SCORE)
79
+
80
+ hash[Contrast::Utils::StringUtils.normalized_key(name)] = value
84
81
  end
82
+ hash
85
83
  end
86
84
  end
87
85
 
@@ -90,7 +88,10 @@ module Contrast
90
88
  # (can't use body because it might be nil)
91
89
  @_body_read ||= begin
92
90
  body = rack_request.body
93
- if defined?(Rack::Multipart) && defined?(Rack::Multipart::UploadedFile) && body.is_a?(Rack::Multipart::UploadedFile)
91
+ if defined?(Rack::Multipart) &&
92
+ defined?(Rack::Multipart::UploadedFile) &&
93
+ body.is_a?(Rack::Multipart::UploadedFile)
94
+
94
95
  logger.trace("not parsing uploaded file body :: #{ body.original_filename }::#{ body.content_type }")
95
96
  @_body = nil
96
97
  else
@@ -5,8 +5,8 @@ require 'contrast/utils/timer'
5
5
  require 'contrast/agent/request'
6
6
  require 'contrast/agent/response'
7
7
  require 'contrast/utils/inventory_util'
8
- require 'contrast/components/interface'
9
- require 'contrast/delegators/input_analysis'
8
+ require 'contrast/components/logger'
9
+ require 'contrast/components/scope'
10
10
 
11
11
  module Contrast
12
12
  module Agent
@@ -26,20 +26,19 @@ module Contrast
26
26
  # @attr_reader route [Contrast::Api::Dtm::RouteCoverage] the route, used for findings, of this request
27
27
  # @attr_reader observed_route [Contrast::Api::Dtm::ObservedRoute] the route, used for coverage, of this request
28
28
  class RequestContext
29
- include Contrast::Components::Interface
30
- access_component :agent, :analysis, :logging, :scope
29
+ include Contrast::Components::Logger::InstanceMethods
30
+ include Contrast::Components::Scope::InstanceMethods
31
31
 
32
32
  EMPTY_INPUT_ANALYSIS_PB = Contrast::Api::Settings::InputAnalysis.new
33
33
 
34
- attr_reader :activity, :logging_hash, :observed_route, :request, :response, :route, :speedracer_input_analysis, :server_activity, :timer
34
+ attr_reader :activity, :logging_hash, :observed_route, :request, :response, :route, :speedracer_input_analysis,
35
+ :server_activity, :timer
35
36
 
36
37
  def initialize rack_request, app_loaded = true
37
38
  with_contrast_scope do
38
39
  # all requests get a timer and hash
39
40
  @timer = Contrast::Utils::Timer.new
40
- @logging_hash = {
41
- request_id: __id__
42
- }
41
+ @logging_hash = { request_id: __id__ }
43
42
 
44
43
  # instantiate helper for request and response
45
44
  @request = Contrast::Agent::Request.new(rack_request)
@@ -64,9 +63,11 @@ module Contrast
64
63
 
65
64
  @sample = true
66
65
 
67
- @sample_request, @sample_response = Contrast::Utils::Assess::SamplingUtil.instance.sample?(@request) if ASSESS.enabled?
66
+ if ::Contrast::ASSESS.enabled?
67
+ @sample_request, @sample_response = Contrast::Utils::Assess::SamplingUtil.instance.sample?(@request)
68
+ end
68
69
 
69
- @sample_response &&= ASSESS.scan_response?
70
+ @sample_response &&= ::Contrast::ASSESS.scan_response?
70
71
 
71
72
  append_route_coverage(Contrast::Agent.framework_manager.get_route_dtm(@request))
72
73
  end
@@ -119,8 +120,8 @@ module Contrast
119
120
  end
120
121
 
121
122
  def service_extract_request
122
- return false unless AGENT.enabled?
123
- return false unless PROTECT.enabled?
123
+ return false unless ::Contrast::AGENT.enabled?
124
+ return false unless ::Contrast::PROTECT.enabled?
124
125
  return false if @do_not_track
125
126
 
126
127
  service_response = Contrast::Agent.messaging_queue.send_event_immediately(@activity.http_request)
@@ -200,7 +201,7 @@ module Contrast
200
201
  attack_results_by_rule = {}
201
202
  agent_settings.input_analysis.results.each do |ia_result|
202
203
  rule_id = ia_result.rule_id
203
- rule = PROTECT.rule(rule_id)
204
+ rule = ::Contrast::PROTECT.rule(rule_id)
204
205
  next unless rule
205
206
 
206
207
  logger.debug('Building attack result from Contrast Service input analysis result', result: ia_result.inspect)
@@ -209,16 +210,10 @@ module Contrast
209
210
  # special case for rules (like reflected xss)
210
211
  # that used to have an infilter / block
211
212
  # mode but now are just block at perimeter
212
- rule.build_attack_with_match(
213
- self,
214
- ia_result,
215
- attack_results_by_rule[rule_id],
216
- ia_result.value)
213
+ rule.build_attack_with_match(self, ia_result, attack_results_by_rule[rule_id],
214
+ ia_result.value)
217
215
  else
218
- rule.build_attack_without_match(
219
- self,
220
- ia_result,
221
- attack_results_by_rule[rule_id])
216
+ rule.build_attack_without_match(self, ia_result, attack_results_by_rule[rule_id])
222
217
  end
223
218
  attack_results_by_rule[rule_id] = attack_result
224
219
  end
@@ -1,20 +1,22 @@
1
1
  # Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
2
  # frozen_string_literal: true
3
3
 
4
+ require 'contrast/components/logger'
5
+ require 'contrast/components/scope'
6
+
4
7
  module Contrast
5
8
  module Agent
6
9
  # This class is instantiated when we receive a request and the agent is enabled to process
7
10
  # that request. It holds the ruleset that we perform filtering operations on (currently
8
11
  # prefilter and postfilter).
9
12
  class RequestHandler
10
- include Contrast::Components::Interface
11
- access_component :agent, :logging, :scope
13
+ include Contrast::Components::Logger::InstanceMethods
12
14
 
13
15
  attr_reader :ruleset, :context
14
16
 
15
17
  def initialize context
16
18
  @context = context
17
- @ruleset = AGENT.ruleset
19
+ @ruleset = ::Contrast::AGENT.ruleset
18
20
  end
19
21
 
20
22
  def send_activity_messages
@@ -7,7 +7,7 @@ require 'timeout'
7
7
  require 'contrast/utils/object_share'
8
8
  require 'contrast/utils/string_utils'
9
9
  require 'contrast/utils/hash_digest'
10
- require 'contrast/components/interface'
10
+ require 'contrast/components/logger'
11
11
 
12
12
  module Contrast
13
13
  module Agent
@@ -16,8 +16,7 @@ module Contrast
16
16
  # data in a format that the Agent expects, caching those transformations in
17
17
  # order to avoid repeatedly creating Strings & thrashing GC.
18
18
  class Response
19
- include Contrast::Components::Interface
20
- access_component :logging
19
+ include Contrast::Components::Logger::InstanceMethods
21
20
 
22
21
  extend Forwardable
23
22