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.
- checksums.yaml +4 -4
- data/.gitignore +0 -3
- data/.simplecov +1 -0
- data/Rakefile +0 -27
- data/ext/cs__assess_basic_object/cs__assess_basic_object.c +7 -5
- data/ext/cs__assess_kernel/cs__assess_kernel.c +14 -3
- data/ext/cs__assess_kernel/cs__assess_kernel.h +2 -0
- data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +10 -3
- data/ext/cs__assess_marshal_module/cs__assess_marshal_module.h +2 -1
- data/ext/cs__assess_regexp/cs__assess_regexp.c +9 -7
- data/ext/{cs__assess_string_interpolation26/cs__assess_string_interpolation26.c → cs__assess_string_interpolation/cs__assess_string_interpolation.c} +14 -3
- data/ext/{cs__assess_string_interpolation26/cs__assess_string_interpolation26.h → cs__assess_string_interpolation/cs__assess_string_interpolation.h} +1 -1
- data/ext/{cs__assess_string_interpolation26 → cs__assess_string_interpolation}/extconf.rb +0 -0
- data/ext/cs__common/cs__common.c +5 -4
- data/ext/cs__contrast_patch/cs__contrast_patch.c +17 -11
- data/lib/contrast/agent/assess/events/source_event.rb +16 -12
- data/lib/contrast/agent/assess/finalizers/hash.rb +1 -0
- data/lib/contrast/agent/assess/policy/policy_node.rb +6 -0
- data/lib/contrast/agent/assess/policy/propagation_method.rb +8 -42
- data/lib/contrast/agent/assess/policy/propagation_node.rb +8 -0
- data/lib/contrast/agent/assess/policy/propagator/base.rb +2 -0
- data/lib/contrast/agent/assess/policy/propagator/custom.rb +4 -0
- data/lib/contrast/agent/assess/policy/propagator/database_write.rb +5 -0
- data/lib/contrast/agent/assess/policy/propagator/split.rb +3 -0
- data/lib/contrast/agent/assess/policy/source_method.rb +7 -47
- data/lib/contrast/agent/assess/policy/source_node.rb +1 -0
- data/lib/contrast/agent/assess/policy/trigger_method.rb +9 -3
- data/lib/contrast/agent/assess/policy/trigger_node.rb +8 -0
- data/lib/contrast/agent/assess/property/evented.rb +4 -18
- data/lib/contrast/agent/assess/tag.rb +19 -0
- data/lib/contrast/agent/assess/tracker.rb +12 -0
- data/lib/contrast/agent/at_exit_hook.rb +8 -8
- data/lib/contrast/agent/inventory/database_config.rb +6 -3
- data/lib/contrast/agent/inventory/dependency_analysis.rb +5 -4
- data/lib/contrast/agent/inventory/dependency_usage_analysis.rb +11 -11
- data/lib/contrast/agent/inventory/policy/datastores.rb +1 -1
- data/lib/contrast/agent/inventory/policy/policy.rb +1 -1
- data/lib/contrast/agent/middleware.rb +4 -0
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +27 -2
- data/lib/contrast/agent/patching/policy/method_policy.rb +3 -3
- data/lib/contrast/agent/patching/policy/policy.rb +5 -0
- data/lib/contrast/agent/patching/policy/policy_node.rb +6 -0
- data/lib/contrast/agent/patching/policy/trigger_node.rb +3 -0
- data/lib/contrast/agent/protect/policy/applies_deserialization_rule.rb +3 -4
- data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +1 -0
- data/lib/contrast/agent/protect/policy/rule_applicator.rb +2 -2
- data/lib/contrast/agent/protect/rule/base.rb +1 -0
- data/lib/contrast/agent/protect/rule/no_sqli.rb +2 -0
- data/lib/contrast/agent/reporting/reporter.rb +32 -7
- data/lib/contrast/agent/reporting/reporter_heartbeat.rb +22 -18
- data/lib/contrast/agent/reporting/reporting_events/application_defend_activity.rb +17 -21
- data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample_activity.rb +26 -3
- data/lib/contrast/agent/reporting/reporting_events/application_update.rb +5 -24
- data/lib/contrast/agent/reporting/reporting_events/architecture_component.rb +8 -1
- data/lib/contrast/agent/reporting/reporting_events/discovered_route.rb +8 -1
- data/lib/contrast/agent/reporting/reporting_events/finding.rb +7 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_event.rb +10 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_event_object.rb +11 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_event_parent_object.rb +11 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_event_property.rb +12 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_event_signature.rb +10 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_event_source.rb +11 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_event_stack.rb +11 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_event_taint_range.rb +11 -1
- data/lib/contrast/agent/reporting/reporting_events/finding_request.rb +11 -1
- data/lib/contrast/agent/reporting/reporting_events/library_discovery.rb +29 -32
- data/lib/contrast/agent/reporting/reporting_events/library_usage_observation.rb +13 -1
- data/lib/contrast/agent/reporting/reporting_events/observed_library_usage.rb +11 -8
- data/lib/contrast/agent/reporting/reporting_events/observed_route.rb +12 -5
- data/lib/contrast/agent/reporting/reporting_events/preflight_message.rb +8 -1
- data/lib/contrast/agent/reporting/reporting_events/reporting_event.rb +9 -1
- data/lib/contrast/agent/reporting/reporting_events/route_discovery.rb +10 -1
- data/lib/contrast/agent/reporting/reporting_events/route_discovery_observation.rb +11 -4
- data/lib/contrast/agent/reporting/reporting_events/server_activity.rb +0 -8
- data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +1 -4
- data/lib/contrast/agent/reporting/reporting_utilities/dtm_message.rb +0 -22
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +1 -3
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +1 -11
- data/lib/contrast/agent/request.rb +5 -7
- data/lib/contrast/agent/request_context.rb +16 -17
- data/lib/contrast/agent/request_context_extend.rb +8 -9
- data/lib/contrast/agent/request_handler.rb +9 -38
- data/lib/contrast/agent/rule_set.rb +4 -0
- data/lib/contrast/agent/service_heartbeat.rb +3 -4
- data/lib/contrast/agent/static_analysis.rb +7 -12
- data/lib/contrast/agent/telemetry/base.rb +35 -35
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_base.rb +2 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_event.rb +2 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_message.rb +5 -2
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_message_exception.rb +3 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_stack_frame.rb +3 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exceptions.rb +0 -1
- data/lib/contrast/agent/thread_watcher.rb +1 -4
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/agent/worker_thread.rb +10 -0
- data/lib/contrast/api/communication/socket.rb +1 -0
- data/lib/contrast/api/decorators/message.rb +0 -6
- data/lib/contrast/api/decorators.rb +0 -2
- data/lib/contrast/api/dtm.pb.rb +1 -1
- data/lib/contrast/api/settings.pb.rb +1 -1
- data/lib/contrast/components/agent.rb +51 -13
- data/lib/contrast/components/assess.rb +16 -6
- data/lib/contrast/components/config.rb +18 -2
- data/lib/contrast/components/contrast_service.rb +1 -1
- data/lib/contrast/components/heap_dump.rb +51 -1
- data/lib/contrast/components/inventory.rb +19 -13
- data/lib/contrast/components/logger.rb +18 -0
- data/lib/contrast/config/assess_configuration.rb +28 -0
- data/lib/contrast/config/base_configuration.rb +8 -15
- data/lib/contrast/config/root_configuration.rb +12 -8
- data/lib/contrast/config/ruby_configuration.rb +2 -9
- data/lib/contrast/config/service_configuration.rb +4 -4
- data/lib/contrast/config.rb +0 -6
- data/lib/contrast/configuration.rb +0 -2
- data/lib/contrast/extension/assess/eval_trigger.rb +0 -4
- data/lib/contrast/extension/assess/hash.rb +3 -2
- data/lib/contrast/extension/assess/kernel.rb +22 -0
- data/lib/contrast/extension/assess/marshal.rb +16 -0
- data/lib/contrast/extension/assess/string.rb +21 -20
- data/lib/contrast/extension/object.rb +19 -0
- data/lib/contrast/framework/base_support.rb +8 -0
- data/lib/contrast/framework/manager.rb +6 -20
- data/lib/contrast/framework/manager_extend.rb +0 -1
- data/lib/contrast/framework/rails/patch/action_controller_live_buffer.rb +11 -16
- data/lib/contrast/framework/rails/support.rb +4 -1
- data/lib/contrast/logger/aliased_logging.rb +2 -0
- data/lib/contrast/logger/log.rb +2 -1
- data/lib/contrast/utils/assess/event_limit_utils.rb +96 -0
- data/lib/contrast/utils/assess/propagation_method_utils.rb +27 -7
- data/lib/contrast/utils/assess/source_method_utils.rb +0 -9
- data/lib/contrast/utils/log_utils.rb +2 -2
- data/lib/contrast/utils/lru_cache.rb +3 -0
- data/lib/contrast/utils/middleware_utils.rb +2 -0
- data/lib/contrast/utils/patching/policy/patch_utils.rb +6 -23
- data/lib/contrast/utils/telemetry_client.rb +7 -7
- data/lib/contrast.rb +37 -18
- data/lib/protobuf/code_generator.rb +129 -0
- data/lib/protobuf/decoder.rb +28 -0
- data/lib/protobuf/deprecation.rb +117 -0
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +79 -0
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +360 -0
- data/lib/protobuf/descriptors.rb +3 -0
- data/lib/protobuf/encoder.rb +11 -0
- data/lib/protobuf/enum.rb +365 -0
- data/lib/protobuf/exceptions.rb +9 -0
- data/lib/protobuf/field/base_field.rb +380 -0
- data/lib/protobuf/field/base_field_object_definitions.rb +504 -0
- data/lib/protobuf/field/bool_field.rb +64 -0
- data/lib/protobuf/field/bytes_field.rb +67 -0
- data/lib/protobuf/field/double_field.rb +25 -0
- data/lib/protobuf/field/enum_field.rb +56 -0
- data/lib/protobuf/field/field_array.rb +102 -0
- data/lib/protobuf/field/field_hash.rb +122 -0
- data/lib/protobuf/field/fixed32_field.rb +25 -0
- data/lib/protobuf/field/fixed64_field.rb +28 -0
- data/lib/protobuf/field/float_field.rb +43 -0
- data/lib/protobuf/field/int32_field.rb +21 -0
- data/lib/protobuf/field/int64_field.rb +34 -0
- data/lib/protobuf/field/integer_field.rb +23 -0
- data/lib/protobuf/field/message_field.rb +51 -0
- data/lib/protobuf/field/sfixed32_field.rb +27 -0
- data/lib/protobuf/field/sfixed64_field.rb +28 -0
- data/lib/protobuf/field/signed_integer_field.rb +29 -0
- data/lib/protobuf/field/sint32_field.rb +21 -0
- data/lib/protobuf/field/sint64_field.rb +21 -0
- data/lib/protobuf/field/string_field.rb +51 -0
- data/lib/protobuf/field/uint32_field.rb +21 -0
- data/lib/protobuf/field/uint64_field.rb +21 -0
- data/lib/protobuf/field/varint_field.rb +77 -0
- data/lib/protobuf/field.rb +74 -0
- data/lib/protobuf/generators/base.rb +85 -0
- data/lib/protobuf/generators/enum_generator.rb +39 -0
- data/lib/protobuf/generators/extension_generator.rb +27 -0
- data/lib/protobuf/generators/field_generator.rb +193 -0
- data/lib/protobuf/generators/file_generator.rb +262 -0
- data/lib/protobuf/generators/group_generator.rb +122 -0
- data/lib/protobuf/generators/message_generator.rb +104 -0
- data/lib/protobuf/generators/option_generator.rb +17 -0
- data/lib/protobuf/generators/printable.rb +160 -0
- data/lib/protobuf/generators/service_generator.rb +50 -0
- data/lib/protobuf/lifecycle.rb +33 -0
- data/lib/protobuf/logging.rb +39 -0
- data/lib/protobuf/message/fields.rb +233 -0
- data/lib/protobuf/message/serialization.rb +85 -0
- data/lib/protobuf/message.rb +241 -0
- data/lib/protobuf/optionable.rb +72 -0
- data/lib/protobuf/tasks/compile.rake +80 -0
- data/lib/protobuf/tasks.rb +1 -0
- data/lib/protobuf/varint.rb +20 -0
- data/lib/protobuf/varint_pure.rb +31 -0
- data/lib/protobuf/version.rb +3 -0
- data/lib/protobuf/wire_type.rb +10 -0
- data/lib/protobuf.rb +91 -0
- data/proto/dynamic_discovery.proto +46 -0
- data/proto/google/protobuf/compiler/plugin.proto +183 -0
- data/proto/google/protobuf/descriptor.proto +911 -0
- data/proto/rpc.proto +71 -0
- data/resources/assess/policy.json +6 -23
- data/ruby-agent.gemspec +4 -2
- metadata +122 -33
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exceptions_report.rb +0 -30
- data/lib/contrast/api/decorators/application_update.rb +0 -44
- data/lib/contrast/api/decorators/library.rb +0 -56
- data/lib/contrast/config/agent_configuration.rb +0 -63
- data/lib/contrast/config/heap_dump_configuration.rb +0 -59
- data/lib/contrast/config/inventory_configuration.rb +0 -33
- data/lib/contrast/config/logger_configuration.rb +0 -26
- 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
|
-
@
|
18
|
-
@
|
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
|
-
@
|
69
|
+
@_enable = true
|
27
70
|
end
|
28
71
|
|
29
72
|
def disable!
|
30
|
-
@
|
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
|
-
|
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?(
|
62
|
-
status:
|
63
|
-
|
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
|
-
|
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/
|
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
|
-
#
|
8
|
-
#
|
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
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
21
|
-
|
22
|
-
@
|
25
|
+
# return [Boolean]
|
26
|
+
def enable
|
27
|
+
@enable.nil? ? true : @enable
|
23
28
|
end
|
24
29
|
|
25
|
-
|
26
|
-
|
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
|
-
|
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::
|
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::
|
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::
|
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::
|
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::
|
52
|
+
# @return [Contrast::Components::Agent::Interface]
|
49
53
|
def agent
|
50
|
-
@agent ||= Contrast::
|
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::
|
72
|
+
# @return [Contrast::Components::Inventory::Interface]
|
69
73
|
def inventory
|
70
|
-
@inventory ||= Contrast::
|
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
|
-
:
|
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? ?
|
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/
|
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::
|
34
|
+
@logger = Contrast::Components::Logger::Interface.new(hsh[:logger])
|
35
35
|
@bypass = hsh[:bypass]
|
36
36
|
end
|
37
37
|
|
38
|
-
# @return [Contrast::
|
38
|
+
# @return [Contrast::Components::Logger::Interface]
|
39
39
|
def logger
|
40
|
-
@logger ||= Contrast::
|
40
|
+
@logger ||= Contrast::Components::Logger::Interface.new
|
41
41
|
end
|
42
42
|
|
43
43
|
# @return [Boolean, false]
|
data/lib/contrast/config.rb
CHANGED
@@ -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
|
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
|