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
@@ -1,8 +1,8 @@
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/interface'
5
4
  require 'contrast/extension/assess/exec_trigger'
5
+ require 'contrast/components/logger'
6
6
 
7
7
  module Contrast
8
8
  module Extension
@@ -13,11 +13,9 @@ module Contrast
13
13
  # Kernel Module or exposing our methods there.
14
14
  module KernelPropagator
15
15
  class << self
16
- include Contrast::Components::Interface
16
+ extend Contrast::Components::Logger::InstanceMethods
17
17
  include Contrast::Extension::Assess::ExecTrigger
18
18
 
19
- access_component :logging
20
-
21
19
  # We're 'tracking' sprintf now, meaning if anything is tracked on the way
22
20
  # in, the entire result will be tracked out. We're going to take this
23
21
  # approach for now b/c it's fast and easy. I don't super love it, and by
@@ -47,13 +45,7 @@ module Contrast
47
45
  parent_events = []
48
46
  track_sprintf(ret, format_string, args, parent_events)
49
47
 
50
- properties.build_event(
51
- patcher,
52
- ret,
53
- preshift.object,
54
- ret,
55
- preshift.args,
56
- 1)
48
+ properties.build_event(patcher, ret, preshift.object, ret, preshift.args, 1)
57
49
 
58
50
  properties.event.instance_variable_set(:@_parent_events, parent_events)
59
51
  ret
@@ -70,8 +62,7 @@ module Contrast
70
62
  handle_sprintf_array(args, result, parent_events)
71
63
  end
72
64
  rescue StandardError => e
73
- logger.error(
74
- 'Unable to track dataflow through sprintf', e)
65
+ logger.error('Unable to track dataflow through sprintf', e)
75
66
  end
76
67
 
77
68
  def instrument_kernel_track
@@ -1,7 +1,8 @@
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/interface'
4
+ require 'contrast/components/logger'
5
+ require 'contrast/components/scope'
5
6
 
6
7
  module Contrast
7
8
  module Extension
@@ -11,9 +12,8 @@ module Contrast
11
12
  # Hopefully, we'll be in a 'get it right' state soon.
12
13
  # This module is used for our Marshal.load patches
13
14
  class MarshalPropagator
14
- include Contrast::Components::Interface
15
-
16
- access_component :logging, :scope
15
+ extend Contrast::Components::Logger::InstanceMethods
16
+ extend Contrast::Components::Scope::InstanceMethods
17
17
 
18
18
  class << self
19
19
  def cs__load_protect arg
@@ -31,12 +31,8 @@ module Contrast
31
31
  # source might not be all the args passed in, but it is the one we care
32
32
  # about. we could pass in all the args in the last param here if it
33
33
  # becomes an issue in rendering on TS
34
- Contrast::Agent::Assess::Policy::TriggerMethod.build_finding(
35
- trigger_node('Marshal', :load),
36
- source,
37
- self,
38
- ret,
39
- *args)
34
+ Contrast::Agent::Assess::Policy::TriggerMethod.build_finding(trigger_node('Marshal', :load), source,
35
+ self, ret, *args)
40
36
  return unless (properties = Contrast::Agent::Assess::Tracker.properties!(ret))
41
37
 
42
38
  properties.copy_from(source, ret)
@@ -2,7 +2,8 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'contrast/agent/assess/policy/propagation_node'
5
- require 'contrast/components/interface'
5
+ require 'contrast/components/logger'
6
+ require 'contrast/components/scope'
6
7
 
7
8
  module Contrast
8
9
  module Extension
@@ -12,9 +13,9 @@ module Contrast
12
13
  # Contrast::Agent::Assess::Policy::Propagator molds without cluttering up the
13
14
  # Regexp Class or exposing our methods there.
14
15
  class RegexpPropagator
15
- include Contrast::Components::Interface
16
+ extend Contrast::Components::Logger::InstanceMethods
17
+ extend Contrast::Components::Scope::InstanceMethods
16
18
 
17
- access_component :analysis, :logging, :scope
18
19
 
19
20
  REGEXP_EQUAL_SQUIGGLE_HASH = {
20
21
  'id' => 'regexp_100',
@@ -34,7 +35,7 @@ module Contrast
34
35
 
35
36
  class << self
36
37
  def track_equal_squiggle info_hash
37
- return unless ASSESS.enabled?
38
+ return unless ::Contrast::ASSESS.enabled?
38
39
 
39
40
  # Because we have a special case for this propagation,
40
41
  # it falls out of regular scoping. As such, any patch to the `=~` method
@@ -53,12 +54,7 @@ module Contrast
53
54
  return unless (properties = Contrast::Agent::Assess::Tracker.properties!(target))
54
55
 
55
56
  properties.splat_from(string, target)
56
- properties.build_event(
57
- REGEXP_EQUAL_SQUIGGLE_NODE,
58
- target,
59
- self,
60
- result,
61
- [string])
57
+ properties.build_event(REGEXP_EQUAL_SQUIGGLE_NODE, target, self, result, [string])
62
58
  end
63
59
  rescue Exception => e # rubocop:disable Lint/RescueException
64
60
  logger.error('Unable to propagate during Regexp#=~', e)
@@ -2,7 +2,8 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'contrast/agent/assess/policy/propagation_node'
5
- require 'contrast/components/interface'
5
+ require 'contrast/components/logger'
6
+ require 'contrast/components/scope'
6
7
 
7
8
  module Contrast
8
9
  module Extension
@@ -12,9 +13,8 @@ module Contrast
12
13
  # Contrast::Agent::Assess::Policy::Propagator molds without cluttering up the
13
14
  # String Class or exposing our methods there.
14
15
  class StringPropagator
15
- include Contrast::Components::Interface
16
-
17
- access_component :agent, :analysis, :logging, :scope
16
+ extend Contrast::Components::Logger::InstanceMethods
17
+ extend Contrast::Components::Scope::InstanceMethods
18
18
 
19
19
  NODE_HASH = {
20
20
  'class_name' => 'String',
@@ -31,7 +31,7 @@ module Contrast
31
31
 
32
32
  class << self
33
33
  def track_interpolation inputs, result
34
- return unless AGENT.interpolation_enabled?
34
+ return unless ::Contrast::AGENT.interpolation_enabled?
35
35
  return if in_contrast_scope?
36
36
  return unless inputs.any? { |input| Contrast::Agent::Assess::Tracker.tracked?(input) }
37
37
 
@@ -66,7 +66,9 @@ module Contrast
66
66
  def instrument_string_interpolation
67
67
  if @_instrument_string_interpolation.nil?
68
68
  @_instrument_string_interpolation = begin
69
- require 'cs__assess_string_interpolation26/cs__assess_string_interpolation26' if AGENT.patch_interpolation? && Funchook.available?
69
+ if ::Contrast::AGENT.patch_interpolation? && Funchook.available?
70
+ require 'cs__assess_string_interpolation26/cs__assess_string_interpolation26'
71
+ end
70
72
  true
71
73
  rescue StandardError, LoadError => e
72
74
  logger.error('Error loading interpolation patch', e)
@@ -41,13 +41,13 @@ module Kernel # :nodoc:
41
41
 
42
42
  def catch *args, &block
43
43
  # Save current scope level
44
- scope_level = Contrast::Components::Scope::COMPONENT_INTERFACE.scope_for_current_ec.instance_variable_get(:@contrast_scope)
44
+ scope_level = ::Contrast::SCOPE.scope_for_current_ec.instance_variable_get(:@contrast_scope)
45
45
 
46
46
  # Run original catch with block.
47
47
  retval = cs__catch(*args, &block)
48
48
 
49
49
  # Restore scope.
50
- Contrast::Components::Scope::COMPONENT_INTERFACE.scope_for_current_ec.instance_variable_set(:@contrast_scope, scope_level)
50
+ ::Contrast::SCOPE.scope_for_current_ec.instance_variable_set(:@contrast_scope, scope_level)
51
51
 
52
52
  retval
53
53
  end
@@ -1,8 +1,6 @@
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/interface'
5
-
6
4
  module Contrast
7
5
  module Extension
8
6
  module Protect
@@ -10,9 +8,6 @@ module Contrast
10
8
  # allowing us to track activity as it crosses spawned processes.
11
9
  module Kernel
12
10
  class << self
13
- include Contrast::Components::Interface
14
- access_component :contrast_service
15
-
16
11
  def build_wrapper
17
12
  lambda {
18
13
  proc_start
@@ -1,26 +1,24 @@
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'
4
5
  require 'contrast/framework/platform_version'
5
6
  require 'contrast/framework/rack/support'
6
7
  require 'contrast/framework/rails/support'
7
8
  require 'contrast/framework/sinatra/support'
8
- require 'contrast/components/interface'
9
9
  require 'contrast/utils/class_util'
10
10
 
11
11
  module Contrast
12
12
  module Framework
13
13
  # Allows access to framework specific information
14
14
  class Manager
15
- include Contrast::Components::Interface
16
- access_component :analysis, :logging
15
+ include Contrast::Components::Logger::InstanceMethods
17
16
 
18
17
  # Order here does matter as the first framework listed will be the first one we pull information from
19
18
  # Rack will be a special case that may involve updating some logic to handle only applying Rack if Rails/Sinatra
20
19
  # do not exist
21
20
  SUPPORTED_FRAMEWORKS = [
22
- Contrast::Framework::Rails::Support,
23
- Contrast::Framework::Sinatra::Support,
21
+ Contrast::Framework::Rails::Support, Contrast::Framework::Sinatra::Support,
24
22
  Contrast::Framework::Rack::Support
25
23
  ].cs__freeze
26
24
 
@@ -1,7 +1,8 @@
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/interface'
4
+ require 'contrast/components/logger'
5
+ require 'contrast/components/scope'
5
6
 
6
7
  module Contrast
7
8
  module Framework
@@ -11,9 +12,8 @@ module Contrast
11
12
  # runtime detection of insecure configurations on individual cookies
12
13
  # within the application
13
14
  class SessionCookie
14
- include Contrast::Components::Interface
15
-
16
- access_component :agent, :analysis, :logging, :scope
15
+ extend Contrast::Components::Logger::InstanceMethods
16
+ extend Contrast::Components::Scope::InstanceMethods
17
17
 
18
18
  CS__SECURE_RULE_NAME = 'secure-flag-missing'
19
19
  CS__HTTPONLY_NAME = 'rails-http-only-disabled'
@@ -36,8 +36,8 @@ module Contrast
36
36
  end
37
37
 
38
38
  def analyze options
39
- return unless AGENT.enabled?
40
- return if ASSESS.forcibly_disabled?
39
+ return unless ::Contrast::AGENT.enabled?
40
+ return if ::Contrast::ASSESS.forcibly_disabled?
41
41
 
42
42
  apply_session_timeout(options)
43
43
  apply_httponly(options)
@@ -61,16 +61,9 @@ module Contrast
61
61
  end
62
62
 
63
63
  def apply_secure_session options
64
- return unless vulnerable_setting?(
65
- :secure,
66
- true,
67
- options,
68
- safe_default: false)
69
-
70
- cs__report_finding(
71
- CS__SECURE_RULE_NAME,
72
- options,
73
- caller_locations(10, 9)[0])
64
+ return unless vulnerable_setting?(:secure, true, options, safe_default: false)
65
+
66
+ cs__report_finding(CS__SECURE_RULE_NAME, options, caller_locations(10, 9)[0])
74
67
  rescue StandardError => e
75
68
  begin
76
69
  logger.error('Unable to track call to secure session', e)
@@ -86,10 +79,7 @@ module Contrast
86
79
  safe_default: false,
87
80
  comparison_type: :greater_than)
88
81
 
89
- cs__report_finding(
90
- CS__SESSION_TIMEOUT_NAME,
91
- options,
92
- caller_locations(10, 9)[0])
82
+ cs__report_finding(CS__SESSION_TIMEOUT_NAME, options, caller_locations(10, 9)[0])
93
83
  rescue StandardError => e
94
84
  begin
95
85
  logger.error('Unable to track call to set session timeout', e)
@@ -101,10 +91,7 @@ module Contrast
101
91
  def apply_httponly options
102
92
  return unless vulnerable_setting?(:httponly, true, options)
103
93
 
104
- cs__report_finding(
105
- CS__HTTPONLY_NAME,
106
- options,
107
- caller_locations(10, 9)[0])
94
+ cs__report_finding(CS__HTTPONLY_NAME, options, caller_locations(10, 9)[0])
108
95
  rescue StandardError => e
109
96
  begin
110
97
  logger.error('Unable to track call to httponly', e)
@@ -12,10 +12,12 @@ module Contrast
12
12
  module Support
13
13
  # (See BaseSupport#after_load_patches)
14
14
  def after_load_patches
15
- Set.new([Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
16
- 'Rack::Session::Cookie',
17
- 'contrast/framework/rack/patch/session_cookie',
18
- instrumenting_module: 'Contrast::Framework::Rack::Patch::SessionCookie')])
15
+ Set.new([
16
+ Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
17
+ 'Rack::Session::Cookie',
18
+ 'contrast/framework/rack/patch/session_cookie',
19
+ instrumenting_module: 'Contrast::Framework::Rack::Patch::SessionCookie')
20
+ ])
19
21
  end
20
22
  end
21
23
  end
@@ -1,7 +1,6 @@
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/interface'
5
4
  require 'contrast/utils/invalid_configuration_util'
6
5
 
7
6
  module Contrast
@@ -10,9 +9,8 @@ module Contrast
10
9
  module Patch
11
10
  # This module is used to analyze rails session storage configuration for assess vulnerabilities
12
11
  module AssessConfiguration
13
- include Contrast::Components::Interface
12
+ include Contrast::Components::Logger::InstanceMethods
14
13
 
15
- access_component :agent, :analysis, :logging
16
14
 
17
15
  CS__SESSION_TIMEOUT_NAME = 'session-timeout'
18
16
  SAFE_SESSION_TIMEOUT = (30 * 60 * 1000)
@@ -23,7 +21,7 @@ module Contrast
23
21
  include Contrast::Utils::InvalidConfigurationUtil
24
22
 
25
23
  def analyze_session_store *args
26
- return if ASSESS.forcibly_disabled?
24
+ return if ::Contrast::ASSESS.forcibly_disabled?
27
25
 
28
26
  apply_httponly_disabled(*args)
29
27
  apply_secure_cookie_disabled(*args)
@@ -32,7 +30,11 @@ module Contrast
32
30
 
33
31
  private
34
32
 
35
- def vulnerable_setting? setting_key, safe_settings_value, original_args, safe_default: true, comparison_type: nil
33
+ def vulnerable_setting?(setting_key,
34
+ safe_settings_value,
35
+ original_args,
36
+ safe_default: true,
37
+ comparison_type: nil)
36
38
  # In most cases, Rails is pretty nice and the default value is safe
37
39
  return !safe_default unless original_args && original_args.length > 1
38
40
 
@@ -48,8 +50,9 @@ module Contrast
48
50
  end
49
51
 
50
52
  def apply_session_timeout *args
51
- return if ASSESS.rule_disabled? CS__SESSION_TIMEOUT_NAME
52
- return unless vulnerable_setting?(:expire_after, SAFE_SESSION_TIMEOUT, args, comparison_type: :greater_than, safe_default: false)
53
+ return if ::Contrast::ASSESS.rule_disabled? CS__SESSION_TIMEOUT_NAME
54
+ return unless vulnerable_setting?(:expire_after, SAFE_SESSION_TIMEOUT, args,
55
+ comparison_type: :greater_than, safe_default: false)
53
56
 
54
57
  rails_session_settings = args[1]
55
58
  cs__report_finding(CS__SESSION_TIMEOUT_NAME, rails_session_settings, caller_locations(3, 2)[0])
@@ -62,7 +65,7 @@ module Contrast
62
65
  end
63
66
 
64
67
  def apply_secure_cookie_disabled *args
65
- return if ASSESS.rule_disabled? CS__SECURE_RULE_NAME
68
+ return if ::Contrast::ASSESS.rule_disabled? CS__SECURE_RULE_NAME
66
69
  return unless vulnerable_setting?(:secure, true, args)
67
70
 
68
71
  rails_session_settings = args[1]
@@ -76,7 +79,7 @@ module Contrast
76
79
  end
77
80
 
78
81
  def apply_httponly_disabled *args
79
- return if ASSESS.rule_disabled? CS__HTTPONLY_RULE_NAME
82
+ return if ::Contrast::ASSESS.rule_disabled? CS__HTTPONLY_RULE_NAME
80
83
  return unless vulnerable_setting?(:httponly, true, args)
81
84
 
82
85
  rails_session_settings = args[1]
@@ -20,45 +20,51 @@ module Contrast
20
20
  # (i.e., where we normally patch) we will miss the configuration
21
21
  # and will never be able to report session misconfiguration rules.
22
22
  Contrast::Framework::Rails::Patch::RailsApplicationConfiguration.instrument
23
- require 'contrast/agent/railtie' if ::Rails::VERSION::MAJOR.to_i >= 3
23
+ require 'contrast/framework/rails/railtie' if ::Rails::VERSION::MAJOR.to_i >= 3
24
24
  end
25
25
 
26
26
  # (See BaseSupport#after_load_patches)
27
27
  def after_load_patches
28
- Set.new([
29
- Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
30
- 'ActionController::Live::Buffer',
31
- 'contrast/framework/rails/patch/action_controller_live_buffer',
32
- instrumenting_module: 'Contrast::Framework::Rails::Patch::ActionControllerLiveBuffer'),
33
- Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
34
- 'Rails::Application::Configuration',
35
- 'contrast/framework/rails/patch/rails_application_configuration',
36
- method_to_instrument: :session_store,
37
- instrumenting_module: 'Contrast::Framework::Rails::Patch::RailsApplicationConfiguration'),
38
-
39
- # TODO: RUBY-714 remove w/ EOL of 2.5
40
- #
41
- # @deprecated Everything past here is used for Rewriting and can
42
- # be removed once we no longer support 2.5.
43
- Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
44
- 'ActionController::Railties::Helper::ClassMethods',
45
- 'contrast/framework/rails/rewrite/action_controller_railties_helper_inherited',
46
- method_to_instrument: :inherited,
47
- instrumenting_module: 'Contrast::Framework::Rails::Rewrite::ActionControllerRailtiesHelperInherited'),
48
- Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
49
- 'ActiveRecord::AttributeMethods::Read::ClassMethods',
50
- 'contrast/framework/rails/rewrite/active_record_attribute_methods_read',
51
- instrumenting_module: 'Contrast::Framework::Rails::Rewrite::ActiveRecordAttributeMethodsRead'),
52
- Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
53
- 'ActiveRecord::Scoping::Named::ClassMethods',
54
- 'contrast/framework/rails/rewrite/active_record_named',
55
- instrumenting_module: 'Contrast::Framework::Rails::Rewrite::ActiveRecordNamed'),
56
- Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
57
- 'ActiveRecord::AttributeMethods::TimeZoneConversion::ClassMethods',
58
- 'contrast/framework/rails/rewrite/active_record_time_zone_inherited',
59
- method_to_instrument: :inherited,
60
- instrumenting_module: 'Contrast::Framework::Rails::Rewrite::ActiveRecordTimeZoneInherited')
61
- ])
28
+ patches = Set.new([
29
+ Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
30
+ 'ActionController::Live::Buffer',
31
+ 'contrast/framework/rails/patch/action_controller_live_buffer',
32
+ instrumenting_module: 'Contrast::Framework::Rails::Patch::ActionControllerLiveBuffer'),
33
+ Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
34
+ 'Rails::Application::Configuration',
35
+ 'contrast/framework/rails/patch/rails_application_configuration',
36
+ method_to_instrument: :session_store,
37
+ instrumenting_module: 'Contrast::Framework::Rails::Patch::RailsApplicationConfiguration')
38
+ ])
39
+ if RUBY_VERSION < '2.6.0'
40
+ patches.merge([
41
+ # TODO: RUBY-714 remove w/ EOL of 2.5
42
+ #
43
+ # @deprecated Everything past here is used for Rewriting and can
44
+ # be removed once we no longer support 2.5.
45
+ Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
46
+ 'ActionController::Railties::Helper::ClassMethods',
47
+ 'contrast/framework/rails/rewrite/action_controller_railties_helper_inherited',
48
+ method_to_instrument: :inherited,
49
+ instrumenting_module:
50
+ 'Contrast::Framework::Rails::Rewrite::ActionControllerRailtiesHelperInherited'),
51
+ Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
52
+ 'ActiveRecord::AttributeMethods::Read::ClassMethods',
53
+ 'contrast/framework/rails/rewrite/active_record_attribute_methods_read',
54
+ instrumenting_module:
55
+ 'Contrast::Framework::Rails::Rewrite::ActiveRecordAttributeMethodsRead'),
56
+ Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
57
+ 'ActiveRecord::Scoping::Named::ClassMethods',
58
+ 'contrast/framework/rails/rewrite/active_record_named',
59
+ instrumenting_module: 'Contrast::Framework::Rails::Rewrite::ActiveRecordNamed'),
60
+ Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
61
+ 'ActiveRecord::AttributeMethods::TimeZoneConversion::ClassMethods',
62
+ 'contrast/framework/rails/rewrite/active_record_time_zone_inherited',
63
+ method_to_instrument: :inherited,
64
+ instrumenting_module: 'Contrast::Framework::Rails::Rewrite::ActiveRecordTimeZoneInherited')
65
+ ])
66
+ end
67
+ patches
62
68
  end
63
69
  end
64
70
  end