contrast-agent 3.8.5 → 3.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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