contrast-agent 6.2.0 → 6.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (209) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -3
  3. data/.simplecov +1 -0
  4. data/Rakefile +0 -27
  5. data/ext/cs__assess_basic_object/cs__assess_basic_object.c +7 -5
  6. data/ext/cs__assess_kernel/cs__assess_kernel.c +14 -3
  7. data/ext/cs__assess_kernel/cs__assess_kernel.h +2 -0
  8. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +10 -3
  9. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.h +2 -1
  10. data/ext/cs__assess_regexp/cs__assess_regexp.c +9 -7
  11. data/ext/{cs__assess_string_interpolation26/cs__assess_string_interpolation26.c → cs__assess_string_interpolation/cs__assess_string_interpolation.c} +14 -3
  12. data/ext/{cs__assess_string_interpolation26/cs__assess_string_interpolation26.h → cs__assess_string_interpolation/cs__assess_string_interpolation.h} +1 -1
  13. data/ext/{cs__assess_string_interpolation26 → cs__assess_string_interpolation}/extconf.rb +0 -0
  14. data/ext/cs__common/cs__common.c +5 -4
  15. data/ext/cs__contrast_patch/cs__contrast_patch.c +17 -11
  16. data/lib/contrast/agent/assess/events/source_event.rb +16 -12
  17. data/lib/contrast/agent/assess/finalizers/hash.rb +1 -0
  18. data/lib/contrast/agent/assess/policy/policy_node.rb +6 -0
  19. data/lib/contrast/agent/assess/policy/propagation_method.rb +8 -42
  20. data/lib/contrast/agent/assess/policy/propagation_node.rb +8 -0
  21. data/lib/contrast/agent/assess/policy/propagator/base.rb +2 -0
  22. data/lib/contrast/agent/assess/policy/propagator/custom.rb +4 -0
  23. data/lib/contrast/agent/assess/policy/propagator/database_write.rb +5 -0
  24. data/lib/contrast/agent/assess/policy/propagator/split.rb +3 -0
  25. data/lib/contrast/agent/assess/policy/source_method.rb +7 -47
  26. data/lib/contrast/agent/assess/policy/source_node.rb +1 -0
  27. data/lib/contrast/agent/assess/policy/trigger_method.rb +9 -3
  28. data/lib/contrast/agent/assess/policy/trigger_node.rb +8 -0
  29. data/lib/contrast/agent/assess/property/evented.rb +4 -18
  30. data/lib/contrast/agent/assess/tag.rb +19 -0
  31. data/lib/contrast/agent/assess/tracker.rb +12 -0
  32. data/lib/contrast/agent/at_exit_hook.rb +8 -8
  33. data/lib/contrast/agent/inventory/database_config.rb +6 -3
  34. data/lib/contrast/agent/inventory/dependency_analysis.rb +5 -4
  35. data/lib/contrast/agent/inventory/dependency_usage_analysis.rb +11 -11
  36. data/lib/contrast/agent/inventory/policy/datastores.rb +1 -1
  37. data/lib/contrast/agent/inventory/policy/policy.rb +1 -1
  38. data/lib/contrast/agent/middleware.rb +4 -0
  39. data/lib/contrast/agent/patching/policy/after_load_patcher.rb +27 -2
  40. data/lib/contrast/agent/patching/policy/method_policy.rb +3 -3
  41. data/lib/contrast/agent/patching/policy/policy.rb +5 -0
  42. data/lib/contrast/agent/patching/policy/policy_node.rb +6 -0
  43. data/lib/contrast/agent/patching/policy/trigger_node.rb +3 -0
  44. data/lib/contrast/agent/protect/policy/applies_deserialization_rule.rb +3 -4
  45. data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +1 -0
  46. data/lib/contrast/agent/protect/policy/rule_applicator.rb +2 -2
  47. data/lib/contrast/agent/protect/rule/base.rb +1 -0
  48. data/lib/contrast/agent/protect/rule/no_sqli.rb +2 -0
  49. data/lib/contrast/agent/reporting/reporter.rb +32 -7
  50. data/lib/contrast/agent/reporting/reporter_heartbeat.rb +22 -18
  51. data/lib/contrast/agent/reporting/reporting_events/application_defend_activity.rb +17 -21
  52. data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample.rb +1 -1
  53. data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample_activity.rb +26 -3
  54. data/lib/contrast/agent/reporting/reporting_events/application_update.rb +5 -24
  55. data/lib/contrast/agent/reporting/reporting_events/architecture_component.rb +8 -1
  56. data/lib/contrast/agent/reporting/reporting_events/discovered_route.rb +8 -1
  57. data/lib/contrast/agent/reporting/reporting_events/finding.rb +7 -1
  58. data/lib/contrast/agent/reporting/reporting_events/finding_event.rb +10 -1
  59. data/lib/contrast/agent/reporting/reporting_events/finding_event_object.rb +11 -1
  60. data/lib/contrast/agent/reporting/reporting_events/finding_event_parent_object.rb +11 -1
  61. data/lib/contrast/agent/reporting/reporting_events/finding_event_property.rb +12 -1
  62. data/lib/contrast/agent/reporting/reporting_events/finding_event_signature.rb +10 -1
  63. data/lib/contrast/agent/reporting/reporting_events/finding_event_source.rb +11 -1
  64. data/lib/contrast/agent/reporting/reporting_events/finding_event_stack.rb +11 -1
  65. data/lib/contrast/agent/reporting/reporting_events/finding_event_taint_range.rb +11 -1
  66. data/lib/contrast/agent/reporting/reporting_events/finding_request.rb +11 -1
  67. data/lib/contrast/agent/reporting/reporting_events/library_discovery.rb +29 -32
  68. data/lib/contrast/agent/reporting/reporting_events/library_usage_observation.rb +13 -1
  69. data/lib/contrast/agent/reporting/reporting_events/observed_library_usage.rb +11 -8
  70. data/lib/contrast/agent/reporting/reporting_events/observed_route.rb +12 -5
  71. data/lib/contrast/agent/reporting/reporting_events/preflight_message.rb +8 -1
  72. data/lib/contrast/agent/reporting/reporting_events/reporting_event.rb +9 -1
  73. data/lib/contrast/agent/reporting/reporting_events/route_discovery.rb +10 -1
  74. data/lib/contrast/agent/reporting/reporting_events/route_discovery_observation.rb +11 -4
  75. data/lib/contrast/agent/reporting/reporting_events/server_activity.rb +0 -8
  76. data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +1 -4
  77. data/lib/contrast/agent/reporting/reporting_utilities/dtm_message.rb +0 -22
  78. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +1 -3
  79. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +1 -11
  80. data/lib/contrast/agent/request.rb +5 -7
  81. data/lib/contrast/agent/request_context.rb +16 -17
  82. data/lib/contrast/agent/request_context_extend.rb +8 -9
  83. data/lib/contrast/agent/request_handler.rb +9 -38
  84. data/lib/contrast/agent/rule_set.rb +4 -0
  85. data/lib/contrast/agent/service_heartbeat.rb +3 -4
  86. data/lib/contrast/agent/static_analysis.rb +7 -12
  87. data/lib/contrast/agent/telemetry/base.rb +35 -35
  88. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_base.rb +2 -0
  89. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_event.rb +2 -0
  90. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_message.rb +5 -2
  91. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_message_exception.rb +3 -0
  92. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_stack_frame.rb +3 -0
  93. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exceptions.rb +0 -1
  94. data/lib/contrast/agent/thread_watcher.rb +1 -4
  95. data/lib/contrast/agent/version.rb +1 -1
  96. data/lib/contrast/agent/worker_thread.rb +10 -0
  97. data/lib/contrast/api/communication/socket.rb +1 -0
  98. data/lib/contrast/api/decorators/message.rb +0 -6
  99. data/lib/contrast/api/decorators.rb +0 -2
  100. data/lib/contrast/api/dtm.pb.rb +1 -1
  101. data/lib/contrast/api/settings.pb.rb +1 -1
  102. data/lib/contrast/components/agent.rb +51 -13
  103. data/lib/contrast/components/assess.rb +16 -6
  104. data/lib/contrast/components/config.rb +18 -2
  105. data/lib/contrast/components/contrast_service.rb +1 -1
  106. data/lib/contrast/components/heap_dump.rb +51 -1
  107. data/lib/contrast/components/inventory.rb +19 -13
  108. data/lib/contrast/components/logger.rb +18 -0
  109. data/lib/contrast/config/assess_configuration.rb +28 -0
  110. data/lib/contrast/config/base_configuration.rb +8 -15
  111. data/lib/contrast/config/root_configuration.rb +12 -8
  112. data/lib/contrast/config/ruby_configuration.rb +2 -9
  113. data/lib/contrast/config/service_configuration.rb +4 -4
  114. data/lib/contrast/config.rb +0 -6
  115. data/lib/contrast/configuration.rb +0 -2
  116. data/lib/contrast/extension/assess/eval_trigger.rb +0 -4
  117. data/lib/contrast/extension/assess/hash.rb +3 -2
  118. data/lib/contrast/extension/assess/kernel.rb +22 -0
  119. data/lib/contrast/extension/assess/marshal.rb +16 -0
  120. data/lib/contrast/extension/assess/string.rb +21 -20
  121. data/lib/contrast/extension/object.rb +19 -0
  122. data/lib/contrast/framework/base_support.rb +8 -0
  123. data/lib/contrast/framework/manager.rb +6 -20
  124. data/lib/contrast/framework/manager_extend.rb +0 -1
  125. data/lib/contrast/framework/rails/patch/action_controller_live_buffer.rb +11 -16
  126. data/lib/contrast/framework/rails/support.rb +4 -1
  127. data/lib/contrast/logger/aliased_logging.rb +2 -0
  128. data/lib/contrast/logger/log.rb +2 -1
  129. data/lib/contrast/utils/assess/event_limit_utils.rb +96 -0
  130. data/lib/contrast/utils/assess/propagation_method_utils.rb +27 -7
  131. data/lib/contrast/utils/assess/source_method_utils.rb +0 -9
  132. data/lib/contrast/utils/log_utils.rb +2 -2
  133. data/lib/contrast/utils/lru_cache.rb +3 -0
  134. data/lib/contrast/utils/middleware_utils.rb +2 -0
  135. data/lib/contrast/utils/patching/policy/patch_utils.rb +6 -23
  136. data/lib/contrast/utils/telemetry_client.rb +7 -7
  137. data/lib/contrast.rb +37 -18
  138. data/lib/protobuf/code_generator.rb +129 -0
  139. data/lib/protobuf/decoder.rb +28 -0
  140. data/lib/protobuf/deprecation.rb +117 -0
  141. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +79 -0
  142. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +360 -0
  143. data/lib/protobuf/descriptors.rb +3 -0
  144. data/lib/protobuf/encoder.rb +11 -0
  145. data/lib/protobuf/enum.rb +365 -0
  146. data/lib/protobuf/exceptions.rb +9 -0
  147. data/lib/protobuf/field/base_field.rb +380 -0
  148. data/lib/protobuf/field/base_field_object_definitions.rb +504 -0
  149. data/lib/protobuf/field/bool_field.rb +64 -0
  150. data/lib/protobuf/field/bytes_field.rb +67 -0
  151. data/lib/protobuf/field/double_field.rb +25 -0
  152. data/lib/protobuf/field/enum_field.rb +56 -0
  153. data/lib/protobuf/field/field_array.rb +102 -0
  154. data/lib/protobuf/field/field_hash.rb +122 -0
  155. data/lib/protobuf/field/fixed32_field.rb +25 -0
  156. data/lib/protobuf/field/fixed64_field.rb +28 -0
  157. data/lib/protobuf/field/float_field.rb +43 -0
  158. data/lib/protobuf/field/int32_field.rb +21 -0
  159. data/lib/protobuf/field/int64_field.rb +34 -0
  160. data/lib/protobuf/field/integer_field.rb +23 -0
  161. data/lib/protobuf/field/message_field.rb +51 -0
  162. data/lib/protobuf/field/sfixed32_field.rb +27 -0
  163. data/lib/protobuf/field/sfixed64_field.rb +28 -0
  164. data/lib/protobuf/field/signed_integer_field.rb +29 -0
  165. data/lib/protobuf/field/sint32_field.rb +21 -0
  166. data/lib/protobuf/field/sint64_field.rb +21 -0
  167. data/lib/protobuf/field/string_field.rb +51 -0
  168. data/lib/protobuf/field/uint32_field.rb +21 -0
  169. data/lib/protobuf/field/uint64_field.rb +21 -0
  170. data/lib/protobuf/field/varint_field.rb +77 -0
  171. data/lib/protobuf/field.rb +74 -0
  172. data/lib/protobuf/generators/base.rb +85 -0
  173. data/lib/protobuf/generators/enum_generator.rb +39 -0
  174. data/lib/protobuf/generators/extension_generator.rb +27 -0
  175. data/lib/protobuf/generators/field_generator.rb +193 -0
  176. data/lib/protobuf/generators/file_generator.rb +262 -0
  177. data/lib/protobuf/generators/group_generator.rb +122 -0
  178. data/lib/protobuf/generators/message_generator.rb +104 -0
  179. data/lib/protobuf/generators/option_generator.rb +17 -0
  180. data/lib/protobuf/generators/printable.rb +160 -0
  181. data/lib/protobuf/generators/service_generator.rb +50 -0
  182. data/lib/protobuf/lifecycle.rb +33 -0
  183. data/lib/protobuf/logging.rb +39 -0
  184. data/lib/protobuf/message/fields.rb +233 -0
  185. data/lib/protobuf/message/serialization.rb +85 -0
  186. data/lib/protobuf/message.rb +241 -0
  187. data/lib/protobuf/optionable.rb +72 -0
  188. data/lib/protobuf/tasks/compile.rake +80 -0
  189. data/lib/protobuf/tasks.rb +1 -0
  190. data/lib/protobuf/varint.rb +20 -0
  191. data/lib/protobuf/varint_pure.rb +31 -0
  192. data/lib/protobuf/version.rb +3 -0
  193. data/lib/protobuf/wire_type.rb +10 -0
  194. data/lib/protobuf.rb +91 -0
  195. data/proto/dynamic_discovery.proto +46 -0
  196. data/proto/google/protobuf/compiler/plugin.proto +183 -0
  197. data/proto/google/protobuf/descriptor.proto +911 -0
  198. data/proto/rpc.proto +71 -0
  199. data/resources/assess/policy.json +6 -23
  200. data/ruby-agent.gemspec +4 -2
  201. metadata +122 -33
  202. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exceptions_report.rb +0 -30
  203. data/lib/contrast/api/decorators/application_update.rb +0 -44
  204. data/lib/contrast/api/decorators/library.rb +0 -56
  205. data/lib/contrast/config/agent_configuration.rb +0 -63
  206. data/lib/contrast/config/heap_dump_configuration.rb +0 -59
  207. data/lib/contrast/config/inventory_configuration.rb +0 -33
  208. data/lib/contrast/config/logger_configuration.rb +0 -26
  209. data/lib/contrast/framework/platform_version.rb +0 -22
@@ -3,6 +3,8 @@
3
3
 
4
4
  require 'rubygems/version'
5
5
  require 'contrast/agent/rule_set'
6
+ require 'contrast/components/logger'
7
+ require 'contrast/components/heap_dump'
6
8
 
7
9
  module Contrast
8
10
  module Components
@@ -13,9 +15,50 @@ module Contrast
13
15
  class Interface
14
16
  include Contrast::Components::ComponentBase
15
17
 
18
+ def initialize hsh = {}
19
+ return unless hsh
20
+
21
+ @_enable = hsh[:enable]
22
+ @_start_bundled_service = hsh[:start_bundled_service]
23
+ @_omit_body = hsh[:omit_body]
24
+ @_service = Contrast::Config::ServiceConfiguration.new(hsh[:service])
25
+ @_logger = Contrast::Components::Logger::Interface.new(hsh[:logger])
26
+ @_ruby = Contrast::Config::RubyConfiguration.new(hsh[:ruby])
27
+ @_heap_dump = Contrast::Components::HeapDump::Interface.new(hsh[:heap_dump])
28
+ end
29
+
30
+ # @return [Boolean, true]
31
+ def start_bundled_service?
32
+ @_start_bundled_service.nil? ? true : @_start_bundled_service
33
+ end
34
+
35
+ def service
36
+ return @_service unless @_service.nil?
37
+
38
+ @_service = Contrast::Config::ServiceConfiguration.new
39
+ end
40
+
41
+ def logger
42
+ return @_logger unless @_logger.nil?
43
+
44
+ @_logger = Contrast::Components::Logger::Interface.new
45
+ end
46
+
47
+ def ruby
48
+ return @_ruby unless @_ruby.nil?
49
+
50
+ @_ruby = Contrast::Config::RubyConfiguration.new
51
+ end
52
+
53
+ def heap_dump
54
+ return @_heap_dump unless @_heap_dump.nil?
55
+
56
+ @_heap_dump = Contrast::Components::HeapDump::Interface.new
57
+ end
58
+
16
59
  def enabled?
17
- @_enabled = !false?(::Contrast::CONFIG.root.enable) if @_enabled.nil?
18
- @_enabled
60
+ @_enable = !false?(::Contrast::CONFIG.root.enable) if @_enable.nil?
61
+ @_enable
19
62
  end
20
63
 
21
64
  def disabled?
@@ -23,11 +66,11 @@ module Contrast
23
66
  end
24
67
 
25
68
  def enable!
26
- @_enabled = true
69
+ @_enable = true
27
70
  end
28
71
 
29
72
  def disable!
30
- @_enabled = false
73
+ @_enable = false
31
74
  Contrast::Agent::TracePointHook.disable
32
75
  Contrast::Agent.thread_watcher&.shutdown!
33
76
  end
@@ -41,8 +84,7 @@ module Contrast
41
84
  end
42
85
 
43
86
  def patch_yield?
44
- @_patch_yield = !false?(::Contrast::CONFIG.root.agent.ruby.propagate_yield) if @_patch_yield.nil?
45
- @_patch_yield
87
+ !false?(ruby.propagate_yield)
46
88
  end
47
89
 
48
90
  def interpolation_enabled?
@@ -52,18 +94,14 @@ module Contrast
52
94
  end
53
95
 
54
96
  def omit_body?
55
- @_omit_body = true?(::Contrast::CONFIG.root.agent.omit_body) if @_omit_body.nil?
56
97
  @_omit_body
57
98
  end
58
99
 
59
100
  def exception_control
60
101
  @_exception_control ||= {
61
- enable: true?(::Contrast::CONFIG.root.agent.ruby.exceptions.capture),
62
- status:
63
- ::Contrast::CONFIG.root.agent.ruby.exceptions.override_status || 403,
64
- message:
65
- ::Contrast::CONFIG.root.agent.ruby.exceptions.override_message ||
66
- Contrast::Utils::ObjectShare::OVERRIDE_MESSAGE
102
+ enable: true?(ruby.exceptions.capture),
103
+ status: ruby.exceptions.override_status || 403,
104
+ message: ruby.exceptions.override_message || Contrast::Utils::ObjectShare::OVERRIDE_MESSAGE
67
105
  }
68
106
  end
69
107
 
@@ -76,12 +76,6 @@ module Contrast
76
76
  @_scan_response
77
77
  end
78
78
 
79
- def track_frozen_sources?
80
- @_track_frozen_sources = !false?(::Contrast::CONFIG.root.agent.ruby.track_frozen_sources) if
81
- @_track_frozen_sources.nil?
82
- @_track_frozen_sources
83
- end
84
-
85
79
  def require_scan?
86
80
  @_require_scan = !false?(::Contrast::CONFIG.root.agent.ruby.require_scan) if @_require_scan.nil?
87
81
  @_require_scan
@@ -124,6 +118,22 @@ module Contrast
124
118
  ::Contrast::SETTINGS.assess_state.session_id
125
119
  end
126
120
 
121
+ def max_source_events
122
+ ::Contrast::CONFIG.root.assess.max_context_source_events
123
+ end
124
+
125
+ def max_propagation_events
126
+ ::Contrast::CONFIG.root.assess.max_propagation_events
127
+ end
128
+
129
+ def time_limit_threshold
130
+ ::Contrast::CONFIG.root.assess.time_limit_threshold
131
+ end
132
+
133
+ def max_rule_reported
134
+ ::Contrast::CONFIG.root.assess.max_rule_reported
135
+ end
136
+
127
137
  private
128
138
 
129
139
  def forcibly_enabled?
@@ -27,7 +27,7 @@ module Contrast
27
27
  CONTRAST_LOG = 'contrast_agent.log'
28
28
  CONTRAST_NAME = 'Contrast Agent'
29
29
 
30
- class Interface # :nodoc:
30
+ class Interface # :nodoc: # rubocop:disable Metrics/ClassLength
31
31
  SESSION_VARIABLES = 'Invalid configuration. '\
32
32
  "Setting both application.session_id and application.session_metadata is not allowed.\n"
33
33
  API_URL = "Invalid configuration. Missing a required connection value 'url' is not set."
@@ -57,6 +57,8 @@ module Contrast
57
57
  @config = Contrast::Configuration.new
58
58
  env_overrides
59
59
  validate
60
+ rescue ArgumentError => e
61
+ proto_logger.error('Configuration failed with error: ', e)
60
62
  end
61
63
  alias_method :rebuild, :build
62
64
 
@@ -136,7 +138,7 @@ module Contrast
136
138
  next unless env_key.to_s.start_with?(CONTRAST_ENV_MARKER)
137
139
 
138
140
  config_item = Contrast::Utils::EnvConfigurationItem.new(env_key, env_value)
139
- @config.assign_value_to_path_array(config_item.dot_path_array, config_item.value)
141
+ assign_value_to_path_array(root, config_item.dot_path_array, config_item.value)
140
142
  end
141
143
  end
142
144
 
@@ -193,6 +195,20 @@ module Contrast
193
195
  def logger_path
194
196
  root.agent.logger.path
195
197
  end
198
+
199
+ # Assign the value from an ENV variable to the Contrast::Config::RootConfiguration object, when
200
+ # appropriate.
201
+ #
202
+ # @return nil
203
+ def assign_value_to_path_array current_level, dot_path_array, value
204
+ dot_path_array[0...-1].each do |segment|
205
+ segment = segment.tr('-', '_')
206
+ current_level = current_level.send(segment) if current_level.cs__respond_to?(segment)
207
+ end
208
+ return unless current_level.nil? == false && current_level.cs__respond_to?(dot_path_array[-1])
209
+
210
+ current_level.send("#{ dot_path_array[-1] }=", value)
211
+ end
196
212
  end
197
213
  end
198
214
  end
@@ -29,7 +29,7 @@ module Contrast
29
29
 
30
30
  # Requirement says "must be true" but that
31
31
  # should be "must not be false" -- oops.
32
- @_use_bundled_service ||= !false?(::Contrast::CONFIG.root.agent.start_bundled_service) &&
32
+ @_use_bundled_service ||= !false?(::Contrast::CONFIG.root.agent.start_bundled_service?) &&
33
33
  # Either a valid host or a valid socket
34
34
  # Path validity is the service's problem
35
35
  (LOCALHOST.match?(host) || !!socket_path)
@@ -2,11 +2,61 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'contrast/components/base'
5
- require 'contrast/components/heap_dump'
5
+ require 'contrast/config/base_configuration'
6
6
 
7
7
  module Contrast
8
8
  module Components
9
9
  module HeapDump
10
+ # Interface used to build the HeapDump settings and component.
11
+ class Interface
12
+ include Contrast::Config::BaseConfiguration
13
+
14
+ DEFAULT_PATH = 'contrast_heap_dumps' # saved
15
+ DEFAULT_MS = 10_000
16
+ DEFAULT_COUNT = 5
17
+
18
+ def initialize hsh = {}
19
+ return unless hsh
20
+
21
+ @_enable = hsh[:enable]
22
+ @_path = hsh[:path]
23
+ @_delay_ms = hsh[:delay_ms]
24
+ @_window_ms = hsh[:window_ms]
25
+ @_count = hsh[:count]
26
+ @_clean = hsh[:clean]
27
+ end
28
+
29
+ # @return [Boolean, String] should dumps be taken
30
+ def enable
31
+ @_enable.nil? ? Contrast::Utils::ObjectShare::FALSE : @_enable
32
+ end
33
+
34
+ # @return [String, DEFAULT_PATH] dir to which dumps should be
35
+ def path
36
+ @_path ||= DEFAULT_PATH
37
+ end
38
+
39
+ # @return [Integer, DEFAULT_MS] time, in ms, after initialization
40
+ def delay_ms
41
+ @_delay_ms ||= DEFAULT_MS
42
+ end
43
+
44
+ # @return [Integer, DEFAULT_MS] ms between each dump
45
+ def window_ms
46
+ @_window_ms ||= DEFAULT_MS
47
+ end
48
+
49
+ # @return [Integer, DEFAULT_COUNT] number of dumps to take
50
+ def count
51
+ @_count ||= DEFAULT_COUNT
52
+ end
53
+
54
+ # @return [Boolean, String] remove temporary objects or not
55
+ def clean
56
+ @_clean.nil? ? Contrast::Utils::ObjectShare::FALSE : @_clean
57
+ end
58
+ end
59
+
10
60
  # A wrapper build around the Common Agent Configuration project to allow
11
61
  # for access of the values contained in its
12
62
  # parent_configuration_spec.yaml.
@@ -1,29 +1,35 @@
1
1
  # Copyright (c) 2022 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/base'
5
+
4
6
  module Contrast
5
7
  module Components
6
8
  module Inventory
7
- # A wrapper build around the Common Agent Configuration project to allow
8
- # for access of the values contained in its
9
- # parent_configuration_spec.yaml.
10
- # Specifically, this allows for querying the state of the Inventory
11
- # product.
9
+ # Interface component for Inventory settings used to store the values from
10
+ # settings file and assert state with check methods.
12
11
  class Interface
13
12
  include Contrast::Components::ComponentBase
14
13
 
15
- def enabled?
16
- @_enabled = !false?(::Contrast::CONFIG.root.inventory.enable) if @_enabled.nil?
17
- @_enabled
14
+ # @return [Array, nil] tags
15
+ attr_accessor :tags
16
+
17
+ def initialize hsh = {}
18
+ return unless hsh
19
+
20
+ @enable = !false?(hsh[:enable])
21
+ @analyze_libraries = !false?(hsh[:analyze_libraries])
22
+ @tags = hsh[:tags]
18
23
  end
19
24
 
20
- def analyze_libraries?
21
- @_analyze_libraries = !false?(::Contrast::CONFIG.root.inventory.analyze_libraries) if @_analyze_libraries.nil?
22
- @_analyze_libraries
25
+ # return [Boolean]
26
+ def enable
27
+ @enable.nil? ? true : @enable
23
28
  end
24
29
 
25
- def tags
26
- ::Contrast::CONFIG.root.inventory&.tags
30
+ # return [Boolean]
31
+ def analyze_libraries
32
+ @analyze_libraries.nil? ? true : @analyze_libraries
27
33
  end
28
34
  end
29
35
  end
@@ -28,8 +28,26 @@ module Contrast
28
28
  end
29
29
  end
30
30
 
31
+ # So This class here follows the update for the configuration
32
+ # and from know on ( if it's as we planned it to be) it will hold the
33
+ # instance methods and will initialize new instances for where they're needed
31
34
  class Interface
32
35
  include InstanceMethods
36
+
37
+ # @return [String, nil]
38
+ attr_accessor :path
39
+ # @return [String, nil]
40
+ attr_accessor :level
41
+ # @return [String, nil]
42
+ attr_accessor :progname
43
+
44
+ def initialize hsh = {}
45
+ return unless hsh
46
+
47
+ @path = hsh[:path]
48
+ @level = hsh[:level]
49
+ @progname = hsh[:progname]
50
+ end
33
51
  end
34
52
  end
35
53
  end
@@ -15,6 +15,10 @@ module Contrast
15
15
  attr_writer :enable_scan_response, :enable_dynamic_sources, :sampling, :rules, :stacktraces
16
16
 
17
17
  DEFAULT_STACKTRACES = 'ALL'
18
+ DEFAULT_MAX_SOURCE_EVENTS = 50_000
19
+ DEFAULT_MAX_PROPAGATION_EVENTS = 50_000
20
+ DEFAULT_MAX_RULE_REPORTED = 50_000
21
+ DEFAULT_MAX_RULE_TIME_THRESHOLD = 300_000
18
22
 
19
23
  def initialize hsh = {}
20
24
  return unless hsh
@@ -27,6 +31,10 @@ module Contrast
27
31
  @sampling = Contrast::Config::SamplingConfiguration.new(hsh[:sampling])
28
32
  @rules = Contrast::Config::AssessRulesConfiguration.new(hsh[:rules])
29
33
  @stacktraces = hsh[:stacktraces]
34
+ @max_context_source_events = hsh[:max_context_source_events]
35
+ @max_propagation_events = hsh[:max_propagation_events]
36
+ @max_rule_reported = hsh[:max_rule_reported]
37
+ @time_limit_threshold = hsh[:time_limit_threshold]
30
38
  end
31
39
 
32
40
  # @return [Boolean, true]
@@ -58,6 +66,26 @@ module Contrast
58
66
  def stacktraces
59
67
  @stacktraces ||= DEFAULT_STACKTRACES
60
68
  end
69
+
70
+ # @return [int] max number of context source events in single request
71
+ def max_context_source_events
72
+ @max_context_source_events ||= DEFAULT_MAX_SOURCE_EVENTS
73
+ end
74
+
75
+ # @return [int] max number of propagation events in single request
76
+ def max_propagation_events
77
+ @max_propagation_events ||= DEFAULT_MAX_PROPAGATION_EVENTS
78
+ end
79
+
80
+ # @return [int] max number of rules reported within time_limit_threshold
81
+ def max_rule_reported
82
+ @max_rule_reported ||= DEFAULT_MAX_RULE_REPORTED
83
+ end
84
+
85
+ # @return [int] max ms threshold for reporting rules
86
+ def time_limit_threshold
87
+ @time_limit_threshold ||= DEFAULT_MAX_RULE_TIME_THRESHOLD
88
+ end
61
89
  end
62
90
  end
63
91
  end
@@ -10,29 +10,22 @@ module Contrast
10
10
  # Configuration settings to usable Ruby classes.
11
11
  module BaseConfiguration
12
12
  extend Forwardable
13
+ AT_UNDERSCORE = '@_'
13
14
 
14
15
  def to_hash
15
16
  hsh = {}
16
17
  instance_variables.each do |iv|
17
- # strip the '@' to get the key
18
- key = iv.to_s[1..]
18
+ # strip the '@' of '@_' to get the key
19
+ string_iv = iv.to_s
20
+ key = if string_iv.include?(AT_UNDERSCORE)
21
+ string_iv[2..]
22
+ else
23
+ string_iv[1..]
24
+ end
19
25
  hsh[key] = send(key.to_sym)
20
26
  end
21
27
  hsh
22
28
  end
23
-
24
- def assign_value_to_path_array dot_path_array, value
25
- current_level = self
26
- dot_path_array[0...-1].each do |segment|
27
- segment = segment.tr('-', '_')
28
- current_level = current_level.send(segment) if current_level.cs__respond_to?(segment)
29
- end
30
- last_entry = dot_path_array[-1]
31
- if current_level.nil? == false && current_level.cs__respond_to?(last_entry)
32
- current_level.send("#{ last_entry }=", value)
33
- end
34
- nil
35
- end
36
29
  end
37
30
  end
38
31
  end
@@ -1,6 +1,9 @@
1
1
  # Copyright (c) 2022 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/agent'
5
+ require 'contrast/components/inventory'
6
+
4
7
  module Contrast
5
8
  module Config
6
9
  # The base of the Common Configuration settings.
@@ -9,7 +12,7 @@ module Contrast
9
12
 
10
13
  # @return [Contrast::Config::ApiConfiguration]
11
14
  attr_writer :api
12
- # @return [Contrast::Config::AgentConfiguration]
15
+ # @return [Contrast::Components::Agent::Interface]
13
16
  attr_writer :agent
14
17
  # @return [Contrast::Config::ApplicationConfiguration]
15
18
  attr_writer :application
@@ -17,7 +20,7 @@ module Contrast
17
20
  attr_writer :server
18
21
  # @return [Contrast::Config::AssessConfiguration]
19
22
  attr_writer :assess
20
- # @return [Contrast::Config::InventoryConfiguration]
23
+ # @return [Contrast::Components::Inventory::Interface]
21
24
  attr_writer :inventory
22
25
  # @return [Contrast::Config::ProtectConfiguration]
23
26
  attr_writer :protect
@@ -26,16 +29,17 @@ module Contrast
26
29
  # @return [Boolean, nil]
27
30
  attr_accessor :enable
28
31
 
32
+ # @raise[ArgumentError]
29
33
  def initialize hsh = {}
30
34
  raise(ArgumentError, 'Expected a hash') unless hsh.is_a?(Hash)
31
35
 
32
36
  @api = Contrast::Config::ApiConfiguration.new(hsh[:api])
33
37
  @enable = hsh[:enable]
34
- @agent = Contrast::Config::AgentConfiguration.new(hsh[:agent])
38
+ @agent = Contrast::Components::Agent::Interface.new(hsh[:agent])
35
39
  @application = Contrast::Config::ApplicationConfiguration.new(hsh[:application])
36
40
  @server = Contrast::Config::ServerConfiguration.new(hsh[:server])
37
41
  @assess = Contrast::Config::AssessConfiguration.new(hsh[:assess])
38
- @inventory = Contrast::Config::InventoryConfiguration.new(hsh[:inventory])
42
+ @inventory = Contrast::Components::Inventory::Interface.new(hsh[:inventory])
39
43
  @protect = Contrast::Config::ProtectConfiguration.new(hsh[:protect])
40
44
  @service = Contrast::Config::ServiceConfiguration.new(hsh[:service])
41
45
  end
@@ -45,9 +49,9 @@ module Contrast
45
49
  @api ||= Contrast::Config::ApiConfiguration.new
46
50
  end
47
51
 
48
- # @return [Contrast::Config::AgentConfiguration]
52
+ # @return [Contrast::Components::Agent::Interface]
49
53
  def agent
50
- @agent ||= Contrast::Config::AgentConfiguration.new
54
+ @agent ||= Contrast::Components::Agent::Interface.new
51
55
  end
52
56
 
53
57
  # @return [Contrast::Config::ApplicationConfiguration]
@@ -65,9 +69,9 @@ module Contrast
65
69
  @assess ||= Contrast::Config::AssessConfiguration.new
66
70
  end
67
71
 
68
- # @return [Contrast::Config::InventoryConfiguration]
72
+ # @return [Contrast::Components::Inventory::Interface]
69
73
  def inventory
70
- @inventory ||= Contrast::Config::InventoryConfiguration.new
74
+ @inventory ||= Contrast::Components::Inventory::Interface.new
71
75
  end
72
76
 
73
77
  # @return [Contrast::Config::ProtectConfiguration]
@@ -21,7 +21,7 @@ module Contrast
21
21
  DEFAULT_UNINSTRUMENTED_NAMESPACES = %w[FactoryGirl FactoryBot].cs__freeze
22
22
 
23
23
  attr_writer :disabled_agent_rake_tasks, :exceptions, :interpolate, :propagate_yield, :require_scan,
24
- :track_frozen_sources, :non_request_tracking, :uninstrument_namespace
24
+ :non_request_tracking, :uninstrument_namespace
25
25
 
26
26
  def initialize hsh = {}
27
27
  return unless hsh
@@ -31,7 +31,6 @@ module Contrast
31
31
  @interpolate = hsh[:interpolate]
32
32
  @propagate_yield = hsh[:propagate_yield]
33
33
  @require_scan = hsh[:require_scan]
34
- @track_frozen_sources = hsh[:track_frozen_sources]
35
34
  @non_request_tracking = hsh[:non_request_tracking]
36
35
  @uninstrument_namespace = hsh[:uninstrument_namespace]
37
36
  end
@@ -67,16 +66,10 @@ module Contrast
67
66
  @require_scan.nil? ? Contrast::Utils::ObjectShare::TRUE : @require_scan
68
67
  end
69
68
 
70
- # controls whether or not we track frozen Strings by replacing them
71
- # @return [Boolean, Contrast::Utils::ObjectShare::TRUE]
72
- def track_frozen_sources
73
- @track_frozen_sources.nil? ? Contrast::Utils::ObjectShare::TRUE : @track_frozen_sources
74
- end
75
-
76
69
  # controls tracking outside of request
77
70
  # @return [Boolean, Contrast::Utils::ObjectShare::FALSE]
78
71
  def non_request_tracking
79
- @non_request_tracking.nil? ? Contrast::Utils::ObjectShare::FALSE : @non_request_tracking
72
+ @non_request_tracking.nil? ? Contrast::Utils::ObjectShare::FALSE : @non_request_tracking
80
73
  end
81
74
 
82
75
  # @return [Array, DEFAULT_UNINSTRUMENTED_NAMESPACES]
@@ -1,7 +1,7 @@
1
1
  # Copyright (c) 2022 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/config/logger_configuration'
4
+ require 'contrast/components/logger'
5
5
 
6
6
  module Contrast
7
7
  module Config
@@ -31,13 +31,13 @@ module Contrast
31
31
  @host = hsh[:host]
32
32
  @port = hsh[:port]
33
33
  @socket = hsh[:socket]
34
- @logger = Contrast::Config::LoggerConfiguration.new(hsh[:logger])
34
+ @logger = Contrast::Components::Logger::Interface.new(hsh[:logger])
35
35
  @bypass = hsh[:bypass]
36
36
  end
37
37
 
38
- # @return [Contrast::Config::LoggerConfiguration]
38
+ # @return [Contrast::Components::Logger::Interface]
39
39
  def logger
40
- @logger ||= Contrast::Config::LoggerConfiguration.new
40
+ @logger ||= Contrast::Components::Logger::Interface.new
41
41
  end
42
42
 
43
43
  # @return [Boolean, false]
@@ -11,10 +11,6 @@ module Contrast
11
11
  end
12
12
 
13
13
  require 'contrast/config/base_configuration'
14
-
15
- require 'contrast/config/logger_configuration'
16
-
17
- require 'contrast/config/heap_dump_configuration'
18
14
  require 'contrast/config/service_configuration'
19
15
  require 'contrast/config/exception_configuration'
20
16
  require 'contrast/config/assess_rules_configuration'
@@ -24,10 +20,8 @@ require 'contrast/config/sampling_configuration'
24
20
 
25
21
  require 'contrast/config/ruby_configuration'
26
22
  require 'contrast/config/api_configuration'
27
- require 'contrast/config/agent_configuration'
28
23
  require 'contrast/config/application_configuration'
29
24
  require 'contrast/config/server_configuration'
30
25
  require 'contrast/config/assess_configuration'
31
- require 'contrast/config/inventory_configuration'
32
26
  require 'contrast/config/protect_configuration'
33
27
  require 'contrast/config/root_configuration'
@@ -18,8 +18,6 @@ module Contrast
18
18
  include Contrast::Components::Scope::InstanceMethods
19
19
  extend Contrast::Components::Scope::InstanceMethods
20
20
 
21
- def_delegator :root, :assign_value_to_path_array
22
-
23
21
  attr_reader :default_name, :root
24
22
 
25
23
  DEFAULT_YAML_PATH = 'contrast_security.yaml'
@@ -25,10 +25,6 @@ module Contrast
25
25
  def apply_trigger obj, source, ret, clazz, method
26
26
  return unless ::Contrast::ASSESS.non_request_tracking? || Contrast::Agent::REQUEST_TRACKER.current
27
27
 
28
- # Since we know this is the source of the trigger, we can do some
29
- # optimization here and return when it is not tracked
30
- return unless Contrast::Utils::Assess::TrackingUtil.tracked?(source)
31
-
32
28
  # source might not be all the args passed in, but it is the one we care
33
29
  # about. we could pass in all the args in the last param here if it
34
30
  # becomes an issue in rendering on TS
@@ -15,11 +15,12 @@ module Contrast
15
15
  class << self
16
16
  def cs__duplicate_and_freeze object
17
17
  return object unless object.is_a?(String) && !object.cs__frozen?
18
- return object unless Contrast::Agent::Assess::Tracker.tracked?(object)
19
18
 
20
19
  # Copy the object, then freeze it, so that it looks the same
21
20
  # externally, but will have our finalizer on it.
22
- object.dup&.cs__freeze
21
+ copy = object.dup
22
+ Contrast::Agent::Assess::Tracker.pre_freeze(copy)
23
+ copy&.cs__freeze
23
24
  rescue StandardError
24
25
  # we'll rescue this error, but we can't log it here as that will
25
26
  # result in a seg fault
@@ -4,6 +4,7 @@
4
4
  require 'contrast/extension/assess/exec_trigger'
5
5
  require 'contrast/components/logger'
6
6
  require 'contrast/agent/assess/events/event_data'
7
+ require 'contrast/agent/patching/policy/patch'
7
8
 
8
9
  module Contrast
9
10
  module Extension
@@ -97,6 +98,27 @@ module Contrast
97
98
  end
98
99
  end
99
100
  end
101
+
102
+ # Used for Kernel exec aliasing since we have no other way of accessing the
103
+ # Kernel#exec under C if we alias it there.
104
+ module ContrastKernel
105
+ # Method to replace the call to Kernel#exec when applying alias patch.
106
+ # It will invoke Contrast::Extension::Assess::KernelPropagator before
107
+ # calling the original method.
108
+ #
109
+ # @param source [String, Proc] Potentially untrusted shell command to execute.
110
+ # @return nil - This method will invoke the Kernel#exec which will
111
+ def cs__kernel_exec source
112
+ # Check if in contrast scope and we have source.
113
+ unless Contrast::Agent::Patching::Policy::Patch.in_contrast_scope? || source.nil?
114
+ Contrast::Agent::Patching::Policy::Patch.with_contrast_scope do
115
+ Contrast::Extension::Assess::KernelPropagator.apply_trigger(source)
116
+ end
117
+ end
118
+ # Call this in the end else any code bellow this call won't be executed.
119
+ Kernel.exec(source)
120
+ end
121
+ end
100
122
  end
101
123
  end
102
124
  end