contrast-agent 3.8.5 → 3.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/ext/cs__assess_array/cs__assess_array.c +1 -1
  3. data/ext/cs__assess_module/cs__assess_module.c +0 -1
  4. data/ext/cs__assess_yield_track/cs__assess_yield_track.c +34 -0
  5. data/ext/cs__assess_yield_track/cs__assess_yield_track.h +12 -0
  6. data/ext/{cs__scope → cs__assess_yield_track}/extconf.rb +0 -0
  7. data/ext/cs__common/cs__common.c +6 -6
  8. data/ext/cs__common/cs__common.h +3 -1
  9. data/ext/cs__contrast_patch/cs__contrast_patch.c +142 -119
  10. data/ext/cs__contrast_patch/cs__contrast_patch.h +3 -0
  11. data/funchook/autom4te.cache/requests +48 -48
  12. data/funchook/config.log +2 -2
  13. data/lib/contrast/agent.rb +15 -5
  14. data/lib/contrast/agent/assess.rb +0 -1
  15. data/lib/contrast/agent/assess/contrast_event.rb +9 -8
  16. data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +68 -18
  17. data/lib/contrast/agent/assess/policy/policy.rb +0 -14
  18. data/lib/contrast/agent/assess/policy/policy_scanner.rb +1 -1
  19. data/lib/contrast/agent/assess/policy/preshift.rb +1 -1
  20. data/lib/contrast/agent/assess/policy/propagation_method.rb +4 -2
  21. data/lib/contrast/agent/assess/policy/propagator/custom.rb +1 -1
  22. data/lib/contrast/agent/assess/policy/propagator/database_write.rb +1 -1
  23. data/lib/contrast/agent/assess/policy/propagator/splat.rb +2 -2
  24. data/lib/contrast/agent/assess/policy/propagator/split.rb +166 -1
  25. data/lib/contrast/agent/assess/policy/rewriter_patch.rb +1 -0
  26. data/lib/contrast/agent/assess/policy/source_method.rb +199 -140
  27. data/lib/contrast/agent/assess/policy/source_validation/cross_site_validator.rb +30 -0
  28. data/lib/contrast/agent/assess/policy/source_validation/source_validation.rb +36 -0
  29. data/lib/contrast/agent/assess/policy/trigger_method.rb +238 -153
  30. data/lib/contrast/agent/assess/policy/trigger_node.rb +54 -9
  31. data/lib/contrast/agent/assess/policy/trigger_validation/trigger_validation.rb +13 -0
  32. data/lib/contrast/agent/assess/properties.rb +29 -0
  33. data/lib/contrast/agent/assess/rule/csrf/csrf_applicator.rb +35 -31
  34. data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +1 -1
  35. data/lib/contrast/agent/class_reopener.rb +98 -55
  36. data/lib/contrast/agent/feature_state.rb +1 -1
  37. data/lib/contrast/agent/inventory/policy/policy.rb +1 -1
  38. data/lib/contrast/agent/logger_manager.rb +2 -2
  39. data/lib/contrast/agent/middleware.rb +1 -3
  40. data/lib/contrast/agent/patching/policy/after_load_patch.rb +40 -4
  41. data/lib/contrast/agent/patching/policy/after_load_patcher.rb +33 -8
  42. data/lib/contrast/agent/patching/policy/method_policy.rb +20 -7
  43. data/lib/contrast/agent/patching/policy/patch.rb +54 -23
  44. data/lib/contrast/agent/patching/policy/patch_status.rb +0 -2
  45. data/lib/contrast/agent/patching/policy/patcher.rb +10 -11
  46. data/lib/contrast/agent/patching/policy/policy.rb +4 -0
  47. data/lib/contrast/agent/patching/policy/policy_node.rb +14 -1
  48. data/lib/contrast/agent/patching/policy/trigger_node.rb +2 -1
  49. data/lib/contrast/agent/protect/policy/policy.rb +6 -6
  50. data/lib/contrast/agent/protect/rule/base.rb +1 -1
  51. data/lib/contrast/agent/protect/rule/deserialization.rb +3 -25
  52. data/lib/contrast/agent/protect/rule/sqli.rb +1 -1
  53. data/lib/contrast/agent/railtie.rb +11 -5
  54. data/lib/contrast/agent/request.rb +1 -19
  55. data/lib/contrast/agent/request_context.rb +1 -1
  56. data/lib/contrast/agent/rewriter.rb +4 -3
  57. data/lib/contrast/agent/scope.rb +116 -19
  58. data/lib/contrast/agent/service_heartbeat.rb +5 -2
  59. data/lib/contrast/agent/settings_state.rb +12 -8
  60. data/lib/contrast/agent/version.rb +1 -1
  61. data/lib/contrast/api.rb +1 -0
  62. data/lib/contrast/api/speedracer.rb +2 -2
  63. data/lib/contrast/components/agent.rb +26 -7
  64. data/lib/contrast/components/app_context.rb +8 -45
  65. data/lib/contrast/components/contrast_service.rb +3 -4
  66. data/lib/contrast/components/interface.rb +1 -1
  67. data/lib/contrast/components/scope.rb +56 -26
  68. data/lib/contrast/config/ruby_configuration.rb +8 -3
  69. data/lib/contrast/delegators.rb +9 -0
  70. data/lib/contrast/delegators/application_update.rb +32 -0
  71. data/lib/contrast/extensions/framework/rack/cookie.rb +24 -0
  72. data/lib/contrast/extensions/framework/rack/request.rb +24 -0
  73. data/lib/contrast/extensions/framework/rack/response.rb +23 -0
  74. data/lib/contrast/extensions/framework/rails/action_controller_railties_helper_inherited.rb +20 -0
  75. data/lib/contrast/extensions/framework/rails/active_record.rb +26 -0
  76. data/lib/contrast/extensions/framework/rails/active_record_named.rb +53 -0
  77. data/lib/contrast/extensions/framework/rails/active_record_time_zone_inherited.rb +21 -0
  78. data/lib/contrast/extensions/framework/rails/buffer.rb +28 -0
  79. data/lib/contrast/extensions/framework/rails/configuration.rb +27 -0
  80. data/lib/contrast/extensions/framework/sinatra/base.rb +59 -0
  81. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess.rb +12 -11
  82. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/array.rb +4 -3
  83. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/assess_extension.rb +0 -2
  84. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/basic_object.rb +1 -1
  85. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/erb.rb +0 -0
  86. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/exec_trigger.rb +0 -0
  87. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/fiber.rb +3 -4
  88. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/hash.rb +0 -0
  89. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/kernel.rb +1 -1
  90. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/module.rb +1 -1
  91. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/regexp.rb +0 -0
  92. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/string.rb +0 -0
  93. data/lib/contrast/{core_extensions → extensions/ruby_core}/assess/tilt_template_trigger.rb +0 -0
  94. data/lib/contrast/extensions/ruby_core/assess/xpath_library_trigger.rb +40 -0
  95. data/lib/contrast/{core_extensions → extensions/ruby_core}/delegator.rb +0 -0
  96. data/lib/contrast/{core_extensions → extensions/ruby_core}/eval_trigger.rb +1 -1
  97. data/lib/contrast/{core_extensions → extensions/ruby_core}/inventory.rb +0 -0
  98. data/lib/contrast/{core_extensions → extensions/ruby_core}/inventory/datastores.rb +1 -1
  99. data/lib/contrast/extensions/ruby_core/module.rb +17 -0
  100. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect.rb +0 -0
  101. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_command_injection_rule.rb +8 -6
  102. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_deserialization_rule.rb +7 -5
  103. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_no_sqli_rule.rb +5 -3
  104. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_path_traversal_rule.rb +31 -27
  105. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_sqli_rule.rb +5 -3
  106. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/applies_xxe_rule.rb +9 -7
  107. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/kernel.rb +0 -0
  108. data/lib/contrast/{core_extensions → extensions/ruby_core}/protect/psych.rb +1 -1
  109. data/lib/contrast/{core_extensions → extensions/ruby_core}/thread.rb +0 -0
  110. data/lib/contrast/framework/base_support.rb +63 -0
  111. data/lib/contrast/framework/manager.rb +109 -0
  112. data/lib/contrast/framework/platform_version.rb +21 -0
  113. data/lib/contrast/framework/rails_support.rb +88 -0
  114. data/lib/contrast/framework/sinatra_application_helper.rb +49 -0
  115. data/lib/contrast/framework/sinatra_support.rb +94 -0
  116. data/lib/contrast/framework/view_technologies_descriptor.rb +20 -0
  117. data/lib/contrast/utils/assess/tracking_util.rb +2 -4
  118. data/lib/contrast/utils/class_util.rb +92 -37
  119. data/lib/contrast/utils/duck_utils.rb +59 -39
  120. data/lib/contrast/utils/environment_util.rb +5 -75
  121. data/lib/contrast/utils/freeze_util.rb +3 -7
  122. data/lib/contrast/utils/invalid_configuration_util.rb +5 -5
  123. data/lib/contrast/utils/job_servers_running.rb +39 -0
  124. data/lib/contrast/utils/ruby_ast_rewriter.rb +2 -2
  125. data/lib/contrast/utils/service_response_util.rb +0 -6
  126. data/lib/contrast/utils/sinatra_helper.rb +6 -0
  127. data/lib/contrast/utils/stack_trace_utils.rb +1 -1
  128. data/resources/assess/policy.json +74 -23
  129. data/resources/inventory/policy.json +1 -1
  130. data/resources/protect/policy.json +11 -9
  131. data/resources/rubocops/object/frozen_cop.rb +1 -1
  132. data/ruby-agent.gemspec +2 -0
  133. data/service_executables/VERSION +1 -1
  134. data/service_executables/linux/contrast-service +0 -0
  135. data/service_executables/mac/contrast-service +0 -0
  136. metadata +94 -57
  137. data/ext/cs__scope/cs__scope.c +0 -96
  138. data/ext/cs__scope/cs__scope.h +0 -33
  139. data/lib/contrast/agent/assess/class_reverter.rb +0 -82
  140. data/lib/contrast/agent/patching/policy/policy_unpatcher.rb +0 -28
  141. data/lib/contrast/core_extensions/module.rb +0 -42
  142. data/lib/contrast/core_extensions/object.rb +0 -27
  143. data/lib/contrast/rails_extensions/assess/action_controller_inheritance.rb +0 -48
  144. data/lib/contrast/rails_extensions/assess/active_record.rb +0 -32
  145. data/lib/contrast/rails_extensions/assess/active_record_named.rb +0 -61
  146. data/lib/contrast/rails_extensions/assess/configuration.rb +0 -26
  147. data/lib/contrast/rails_extensions/buffer.rb +0 -30
  148. data/lib/contrast/rails_extensions/rack.rb +0 -45
  149. data/lib/contrast/sinatra_extensions/assess/cookie.rb +0 -26
  150. data/lib/contrast/sinatra_extensions/inventory/sinatra_base.rb +0 -59
  151. data/lib/contrast/utils/operating_environment.rb +0 -38
  152. data/lib/contrast/utils/path_util.rb +0 -151
  153. data/lib/contrast/utils/scope_util.rb +0 -99
@@ -3,6 +3,6 @@
3
3
 
4
4
  module Contrast
5
5
  module Agent
6
- VERSION = '3.8.5'
6
+ VERSION = '3.9.0'
7
7
  end
8
8
  end
@@ -12,6 +12,7 @@ end
12
12
 
13
13
  cs__scoped_require 'contrast/api/dtm_pb'
14
14
  cs__scoped_require 'contrast/api/settings_pb'
15
+ cs__scoped_require 'contrast/delegators'
15
16
  cs__scoped_require 'contrast/api/unix_socket'
16
17
  cs__scoped_require 'contrast/api/tcp_socket'
17
18
  cs__scoped_require 'contrast/api/speedracer'
@@ -133,8 +133,8 @@ module Contrast
133
133
  message.prefilter = event
134
134
  when Contrast::Api::Dtm::HttpResponse
135
135
  message.postfilter = event
136
- when Contrast::Api::Dtm::Noop
137
- message.noop = event
136
+ when Contrast::Api::Dtm::Poll
137
+ message.poll = event
138
138
  when Contrast::Api::Dtm::ObservedRoute
139
139
  message.observed_route = event
140
140
  else
@@ -1,6 +1,8 @@
1
1
  # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
2
  # frozen_string_literal: true
3
3
 
4
+ cs__scoped_require 'rubygems/version'
5
+
4
6
  module Contrast
5
7
  module Components
6
8
  module Agent
@@ -46,6 +48,10 @@ module Contrast
46
48
  !interpolation_patch_possible?
47
49
  end
48
50
 
51
+ def patch_yield?
52
+ !Contrast::Utils::BooleanUtil.false?(CONFIG.root.agent.ruby.propagate_yield)
53
+ end
54
+
49
55
  def interpolation_enabled?
50
56
  !Contrast::Utils::BooleanUtil.false?(CONFIG.root.agent.ruby.interpolate)
51
57
  end
@@ -54,12 +60,15 @@ module Contrast
54
60
  Contrast::Agent::FeatureState.instance.report_custom_code_sysfile_access?
55
61
  end
56
62
 
57
- # TODO: RUBY-564 Move instrumentation to a new component that handles
58
- # one-time agent initialization procedures.
59
- SHARED_LIBRARIES = %w[contrast/core_extensions/thread
60
- contrast/rails_extensions/rack
61
- contrast/rails_extensions/buffer
62
- contrast/sinatra_extensions/assess/cookie].cs__freeze
63
+ def skip_instrumentation? loaded_module_name
64
+ return true unless loaded_module_name
65
+
66
+ loaded_module_name.start_with?(*CONFIG.root.agent.ruby.uninstrument_namespace)
67
+ end
68
+
69
+ # All this method chain does anymore is load the Thread patch that
70
+ # propagates request contexts. That can go away RUBY-700.
71
+ SHARED_LIBRARIES = %w[contrast/extensions/ruby_core/thread].cs__freeze
63
72
  def run_instrumentation
64
73
  Contrast::Agent::FeatureState.instance.tap do |settings|
65
74
  SHARED_LIBRARIES.each { |lib| settings.instrument lib }
@@ -68,14 +77,24 @@ module Contrast
68
77
  enable_tracepoint # This handles all class loads & required instrumentation going forward
69
78
  end
70
79
 
80
+ # TODO: RUBY-564: This responsibility should be extracted out of this agent component and moved to
81
+ # the new component that handles one-time-whole-app initialization procedures.
82
+ def insert_middleware app
83
+ app.middleware.insert_before 0, Contrast::Agent::Middleware # Keep our middleware at the outermost layer of the onion
84
+ end
85
+
71
86
  def enable_tracepoint
72
87
  Contrast::Agent::TracePointHook.enable!
73
88
  end
74
89
 
75
90
  protected
76
91
 
92
+ INTERPOLATION_HOOKABLE_VERSION = Gem::Version.new('2.6.0')
93
+ # Ruby exposed the C method for interpolation in version 2.6.0, meaning
94
+ # we can attempt to patch using Funchook for that version and later.
77
95
  def interpolation_patch_possible?
78
- Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6.0')
96
+ @_interpolation_patch_possible = Gem::Version.new(RUBY_VERSION) >= INTERPOLATION_HOOKABLE_VERSION if @_interpolation_patch_possible.nil?
97
+ @_interpolation_patch_possible
79
98
  end
80
99
  end
81
100
 
@@ -1,8 +1,8 @@
1
1
  # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
2
  # frozen_string_literal: true
3
3
 
4
- cs__scoped_require 'contrast/core_extensions/object'
5
4
  cs__scoped_require 'contrast/utils/sinatra_helper'
5
+ cs__scoped_require 'rubygems/version'
6
6
 
7
7
  module Contrast
8
8
  module Components
@@ -23,12 +23,6 @@ module Contrast
23
23
  DEFAULT_SERVER_NAME = 'localhost'
24
24
  DEFAULT_SERVER_PATH = '/'
25
25
 
26
- RAILS_TYPE = 'rails'
27
- SINATRA_TYPE = 'sinatra'
28
- RACK_TYPE = 'rack'
29
-
30
- RAILS_MODULE_NAME_VERSION = Gem::Version.new('6.0.0')
31
-
32
26
  def present? str
33
27
  Contrast::Utils::EnvironmentUtil.present?(str)
34
28
  end
@@ -36,29 +30,17 @@ module Contrast
36
30
  def server_type
37
31
  @_server_type ||= begin
38
32
  tmp = CONFIG.root.server.type
39
- tmp = framework_server_name unless present?(tmp)
33
+ tmp = Contrast::Agent.framework_manager.server_type unless present?(tmp)
40
34
  tmp
41
35
  rescue StandardError
42
36
  RACK_TYPE
43
37
  end
44
38
  end
45
39
 
46
- def framework_server_name
47
- @_framework_server_name ||= begin
48
- if defined?(Rails)
49
- RAILS_TYPE
50
- elsif defined?(Sinatra)
51
- SINATRA_TYPE
52
- else
53
- RACK_TYPE
54
- end
55
- end
56
- end
57
-
58
40
  def name
59
41
  @_name ||= begin
60
42
  tmp = CONFIG.root.application.name
61
- tmp = framework_app_name unless present?(tmp)
43
+ tmp = Contrast::Agent.framework_manager.app_name unless present?(tmp)
62
44
  tmp = File.basename(Dir.pwd) unless present?(tmp)
63
45
  Contrast::Utils::StringUtils.truncate(tmp, DEFAULT_APP_NAME)
64
46
  rescue StandardError
@@ -66,14 +48,6 @@ module Contrast
66
48
  end
67
49
  end
68
50
 
69
- def framework_app_name
70
- @_framework_app_name ||= begin
71
- name = find_rails_app_name
72
- name ||= find_sinatra_app_name
73
- name
74
- end
75
- end
76
-
77
51
  def path
78
52
  @_path ||= begin
79
53
  tmp = CONFIG.root.application.path
@@ -154,24 +128,13 @@ module Contrast
154
128
  @_client_id ||= [name, pgid].join('-')
155
129
  end
156
130
 
157
- private
158
-
159
- def find_sinatra_app_name
160
- sinatra_app = Contrast::Utils::SinatraHelper.app_class
161
- return unless sinatra_app
162
-
163
- sinatra_app.cs__class.cs__name
131
+ # TODO: RUBY-564: This responsibility should be extracted out of app_context and moved to
132
+ # the new component that handles one-time-whole-app initialization procedures.
133
+ def instrument_middleware_stack?
134
+ !Contrast::Utils::JobServersRunning.job_servers_running?
164
135
  end
165
136
 
166
- def find_rails_app_name
167
- return nil unless defined?(Rails)
168
-
169
- # Rails version 6.0.0 deprecated Rails::Application#parent_name, in Rails 6.1.0 that method will be removed entirely
170
- # and instead we need to use parent_module_name
171
- return Rails.application.cs__class.parent_module_name if Gem::Version.new(Rails.version) >= RAILS_MODULE_NAME_VERSION
172
-
173
- Rails.application.cs__class.parent_name
174
- end
137
+ private
175
138
 
176
139
  # TODO: RUBY-120, move this responsibility toward the protobuf object
177
140
  def protobuf_format param, truncate: true
@@ -65,12 +65,11 @@ module Contrast
65
65
  # should be "must not be false" -- oops.
66
66
  !false?(CONFIG.root.agent.start_bundled_service) &&
67
67
  # Either a valid host or a valid socket
68
- (CONFIG.root.agent.service.host.nil? ||
68
+ ((CONFIG.root.agent.service.host.nil? ||
69
69
  CONFIG.root.agent.service.host == 'localhost' ||
70
- CONFIG.root.agent.service.host == '127.0.0.1' ||
71
- CONFIG.root.agent.service.host.empty?) ||
70
+ CONFIG.root.agent.service.host == '127.0.0.1') ||
72
71
  # Path validity is the service's problem
73
- !CONFIG.root.agent.service.socket.empty?
72
+ !!CONFIG.root.agent.service.socket)
74
73
  end
75
74
  end
76
75
 
@@ -2,7 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  cs__scoped_require 'delegate'
5
- cs__scoped_require 'contrast/core_extensions/module'
5
+ cs__scoped_require 'contrast/extensions/ruby_core/module'
6
6
  cs__scoped_require 'contrast/utils/boolean_util'
7
7
 
8
8
  module Contrast
@@ -39,33 +39,13 @@ module Contrast
39
39
  end
40
40
 
41
41
  module InstanceMethods # :nodoc:
42
- # These scopes can be meta-defined (RUBY-573)
43
- #
44
- # [:my_cool_scope, :another_good_one].each do |scope|
45
- # define_method "in_#{scope}_scope?" do
46
- # abc
47
- # end
48
- # end
49
-
50
- def in_contrast_scope?
51
- scope_for_current_ec.in_contrast_scope?
52
- end
53
-
54
- def enter_contrast_scope!
55
- scope_for_current_ec.enter_scope_for Contrast::Agent::Scope::CONTRAST_SCOPE
56
- scope_for_current_ec
57
- end
42
+ # For each instance method on a scope, define a forwarder
43
+ # to the scope on the current execution context's scope.
58
44
 
59
- def exit_contrast_scope!
60
- scope_for_current_ec.exit_scope_for Contrast::Agent::Scope::CONTRAST_SCOPE
61
- scope_for_current_ec
62
- end
63
-
64
- def with_contrast_scope
65
- enter_contrast_scope!
66
- yield
67
- ensure
68
- exit_contrast_scope!
45
+ Contrast::Agent::Scope.public_instance_methods(false).each do |method_sym|
46
+ define_method(method_sym) do |*args, &block|
47
+ scope_for_current_ec.send(method_sym, *args, &block)
48
+ end
69
49
  end
70
50
 
71
51
  def scope_for_current_ec
@@ -104,3 +84,53 @@ module Contrast
104
84
  end
105
85
  end
106
86
  end
87
+
88
+ # This is a reasonable place for the Kernel#catch hook to live.
89
+ # No current plans for component re-design, but if we had some kind of
90
+ # "do this when a component is hooked in" thing, this would live there.
91
+ # For now, it's over-engineering to live anywhere else. -ajm
92
+ module Kernel # :nodoc:
93
+ alias_method :cs__catch, :catch
94
+
95
+ # In the event of a `throw`, we need to override `catch`
96
+ # to save & restore scope state:
97
+ #
98
+ # scope_level == 0
99
+ #
100
+ # catch(:abc) do
101
+ # with_contrast_scope do
102
+ # throw :abc # will leak
103
+ # end
104
+ # end
105
+ #
106
+ # scope_level == 1
107
+ #
108
+ # Frankly, this isn't how scope should be used. This is in place of
109
+ # proper `ensure` blocks within the instrumentation call stack.
110
+ # This will actually /create/ scope leaks if you're doing something like:
111
+ #
112
+ # catch(:ohno) do
113
+ # enter scope
114
+ # end
115
+ #
116
+ # abc()
117
+ #
118
+ # exit scope
119
+ #
120
+ # i.e. if you intend to change net scope across a catch block boundary.
121
+
122
+ private
123
+
124
+ def catch *args, &block
125
+ # Save current scope level
126
+ scope_level = Contrast::Components::Scope::COMPONENT_INTERFACE.scope_for_current_ec.instance_variable_get(:@contrast_scope)
127
+
128
+ # Run original catch with block.
129
+ retval = cs__catch(*args, &block)
130
+
131
+ # Restore scope.
132
+ Contrast::Components::Scope::COMPONENT_INTERFACE.scope_for_current_ec.instance_variable_set(:@contrast_scope, scope_level)
133
+
134
+ retval
135
+ end
136
+ end
@@ -25,9 +25,14 @@ module Contrast
25
25
  KEYS = {
26
26
  disabled_agent_rake_tasks: Contrast::Config::DefaultValue.new(DISABLED_RAKE_TASK_LIST),
27
27
  exceptions: Contrast::Config::ExceptionConfiguration,
28
- interpolate: Contrast::Config::DefaultValue.new(Contrast::Utils::ObjectShare::TRUE), # :-(
29
- require_scan: Contrast::Config::DefaultValue.new(Contrast::Utils::ObjectShare::TRUE), # control whether or not we run file scanning rules
30
- track_frozen_sources: EMPTY_VALUE,
28
+ # controls whether or not we patch interpolation, either by rewrite or by funchook
29
+ interpolate: Contrast::Config::DefaultValue.new(Contrast::Utils::ObjectShare::TRUE),
30
+ # controls whether or not we patch the rb_yield block to track split propagation
31
+ propagate_yield: Contrast::Config::DefaultValue.new(Contrast::Utils::ObjectShare::TRUE),
32
+ # control whether or not we run file scanning rules on require
33
+ require_scan: Contrast::Config::DefaultValue.new(Contrast::Utils::ObjectShare::TRUE),
34
+ # controls whether or not we track frozen Strings by replacing them
35
+ track_frozen_sources: Contrast::Config::DefaultValue.new(Contrast::Utils::ObjectShare::TRUE),
31
36
  uninstrument_namespace: Contrast::Config::DefaultValue.new(DEFAULT_UNINSTRUMENTED_NAMESPACES)
32
37
  }.cs__freeze
33
38
 
@@ -0,0 +1,9 @@
1
+ # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ module Contrast
5
+ # Used to define decorators for objects to add behavior without polluting the namespace
6
+ module Delegators
7
+ end
8
+ end
9
+ cs__scoped_require 'contrast/delegators/application_update'
@@ -0,0 +1,32 @@
1
+ # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ module Contrast
5
+ module Delegators
6
+ # Used to decorate the ApplicationUpdate protobuf model so it can own some of the data massaging required for
7
+ # AppUpdate dtm
8
+ class ApplicationUpdate < SimpleDelegator
9
+ def append_view_technology_descriptor_data view_technology_descriptors
10
+ view_technology_descriptors.each do |vtd|
11
+ vtd.technology_names.each do |tech_name|
12
+ @delegate_sd_obj.technologies[tech_name] = true
13
+ end
14
+ end
15
+ end
16
+
17
+ # TS only allows you to report 500 routes per application
18
+ def append_route_coverage_data route_coverage_dtms
19
+ route_coverage_dtms.take(500).each do |route_coverage_dtm|
20
+ @delegate_sd_obj.routes << route_coverage_dtm
21
+ end
22
+ end
23
+
24
+ def append_platform_version platform_version
25
+ @delegate_sd_obj.platform = Contrast::Api::Dtm::Platform.new if @delegate_sd_obj.platform.nil?
26
+ @delegate_sd_obj.platform.major = platform_version.major
27
+ @delegate_sd_obj.platform.minor = platform_version.minor
28
+ @delegate_sd_obj.platform.build = platform_version.patch
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,24 @@
1
+ # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ cs__scoped_require 'contrast/components/interface'
5
+
6
+ module Rack
7
+ module Session
8
+ # Our patch into the Rack::Session::Cookie Class, allowing for the
9
+ # runtime detection of insecure configurations on individual cookies
10
+ # within the application
11
+ class Cookie
12
+ include Contrast::Utils::InvalidConfigurationUtil
13
+ include Contrast::Components::Interface
14
+
15
+ access_component :scope
16
+
17
+ alias_method :cs__patched_initialize, :initialize
18
+ def initialize app, options = {}
19
+ Contrast::Utils::RackAssessSessionCookie.analyze_cookie_initialization(options)
20
+ cs__patched_initialize(app, options)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ # In earlier versions of rack < 2.0.0 the Rack::Response and Rack::Request do
5
+ # not have get_header or set_header methods. This is our way of working
6
+ # around that.
7
+ module Rack
8
+ # Our patch into the Rack::Request class, allowing us to call set_header
9
+ # and get_header in our code without worrying about older versions of
10
+ # Rack not implementing these methods.
11
+ class Request
12
+ unless Rack::Request.instance_methods(true).include?(:set_header)
13
+ def set_header name, value
14
+ @env[name] = value
15
+ end
16
+ end
17
+
18
+ unless Rack::Request.instance_methods(true).include?(:get_header)
19
+ def get_header name
20
+ @env[name]
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ # In earlier versions of rack < 2.0.0 the Rack::Response and Rack::Request do
5
+ # not have get_header or set_header methods. This is our way of working
6
+ # around that.
7
+ module Rack
8
+ # Our patch into the Rack::Response Class, allowing us to call set_header
9
+ # and get_header in our code without worrying about older versions of
10
+ # Rack not implementing these methods.
11
+ class Response
12
+ unless Rack::Response.instance_methods(true).include?(:set_header)
13
+ def set_header key, value
14
+ headers[key] = value
15
+ end
16
+ end
17
+ unless Rack::Response.instance_methods(true).include?(:get_header)
18
+ def get_header key
19
+ headers[key]
20
+ end
21
+ end
22
+ end
23
+ end