contrast-agent 6.13.0 → 6.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/contrast/agent/{assess.rb → assess/assess.rb} +1 -1
- data/lib/contrast/agent/{module_data.rb → assess/module_data.rb} +0 -0
- data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +3 -0
- data/lib/contrast/agent/assess/policy/policy_node.rb +3 -2
- data/lib/contrast/agent/assess/policy/propagation_method.rb +2 -2
- data/lib/contrast/agent/assess/policy/propagator/database_write.rb +0 -1
- data/lib/contrast/agent/assess/policy/source_method.rb +1 -1
- data/lib/contrast/agent/assess/policy/trigger_method.rb +36 -1
- data/lib/contrast/agent/assess/policy/trigger_validation/redos_validator.rb +1 -1
- data/lib/contrast/agent/{excluder.rb → excluder/excluder.rb} +0 -0
- data/lib/contrast/agent/{exclusion_matcher.rb → excluder/exclusion_matcher.rb} +0 -0
- data/lib/contrast/agent/{at_exit_hook.rb → hooks/at_exit_hook.rb} +0 -0
- data/lib/contrast/agent/{tracepoint_hook.rb → hooks/tracepoint_hook.rb} +0 -0
- data/lib/contrast/agent/inventory/database_config.rb +1 -0
- data/lib/contrast/agent/{inventory.rb → inventory/inventory.rb} +0 -0
- data/lib/contrast/agent/{middleware.rb → middleware/middleware.rb} +3 -3
- data/lib/contrast/agent/{static_analysis.rb → middleware/static_analysis.rb} +0 -0
- data/lib/contrast/agent/protect/input_analyzer/input_analyzer.rb +5 -5
- data/lib/contrast/agent/protect/input_analyzer/worth_watching_analyzer.rb +1 -1
- data/lib/contrast/agent/protect/policy/applies_command_injection_rule.rb +1 -1
- data/lib/contrast/agent/protect/policy/applies_deserialization_rule.rb +1 -1
- data/lib/contrast/agent/protect/policy/applies_no_sqli_rule.rb +1 -1
- data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +1 -1
- data/lib/contrast/agent/protect/policy/applies_sqli_rule.rb +1 -1
- data/lib/contrast/agent/protect/policy/applies_xxe_rule.rb +1 -1
- data/lib/contrast/agent/protect/rule/base.rb +121 -134
- data/lib/contrast/agent/protect/rule/{bot_blocker.rb → bot_blocker/bot_blocker.rb} +2 -2
- data/lib/contrast/agent/protect/rule/{cmd_injection.rb → cmdi/cmd_injection.rb} +1 -1
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_backdoors.rb +3 -3
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_base_rule.rb +1 -1
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_chained_command.rb +2 -2
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_dangerous_path.rb +2 -2
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_input_classification.rb +1 -1
- data/lib/contrast/agent/protect/rule/{deserialization.rb → deserialization/deserialization.rb} +2 -2
- data/lib/contrast/agent/protect/rule/{no_sqli.rb → no_sqli/no_sqli.rb} +3 -3
- data/lib/contrast/agent/protect/rule/no_sqli/no_sqli_input_classification.rb +1 -1
- data/lib/contrast/agent/protect/rule/{path_traversal.rb → path_traversal/path_traversal.rb} +2 -2
- data/lib/contrast/agent/protect/rule/path_traversal/path_traversal_semantic_security_bypass.rb +3 -3
- data/lib/contrast/agent/protect/rule/{sql_sample_builder.rb → sqli/sql_sample_builder.rb} +0 -1
- data/lib/contrast/agent/protect/rule/{sqli.rb → sqli/sqli.rb} +2 -2
- data/lib/contrast/agent/protect/rule/sqli/sqli_base_rule.rb +1 -1
- data/lib/contrast/agent/protect/rule/{unsafe_file_upload.rb → unsafe_file_upload/unsafe_file_upload.rb} +2 -2
- data/lib/contrast/agent/protect/rule/unsafe_file_upload/unsafe_file_upload_input_classification.rb +1 -1
- data/lib/contrast/agent/protect/rule/utils/builders.rb +111 -0
- data/lib/contrast/agent/protect/rule/utils/filters.rb +110 -0
- data/lib/contrast/agent/protect/rule/{xss.rb → xss/xss.rb} +2 -2
- data/lib/contrast/agent/protect/rule/{xxe.rb → xxe/xxe.rb} +2 -2
- data/lib/contrast/agent/protect/rule.rb +8 -9
- data/lib/contrast/agent/{disable_reaction.rb → reactions/disable_reaction.rb} +0 -0
- data/lib/contrast/agent/reporting/reporter.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample.rb +3 -3
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_workers/application_server_worker.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_workers/reporter_heartbeat.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_workers/server_settings_worker.rb +1 -1
- data/lib/contrast/agent/{request.rb → request/request.rb} +0 -0
- data/lib/contrast/agent/{request_context.rb → request/request_context.rb} +3 -3
- data/lib/contrast/agent/{request_context_extend.rb → request/request_context_extend.rb} +0 -0
- data/lib/contrast/agent/{request_handler.rb → request/request_handler.rb} +0 -0
- data/lib/contrast/agent/{response.rb → response/response.rb} +0 -0
- data/lib/contrast/agent/{scope.rb → scope/scope.rb} +0 -0
- data/lib/contrast/agent/telemetry/base.rb +2 -2
- data/lib/contrast/agent/{telemetry.rb → telemetry/telemetry.rb} +0 -0
- data/lib/contrast/agent/{thread.rb → thread/thread.rb} +0 -0
- data/lib/contrast/agent/{thread_watcher.rb → thread/thread_watcher.rb} +0 -0
- data/lib/contrast/agent/{worker_thread.rb → thread/worker_thread.rb} +0 -0
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/agent.rb +11 -11
- data/lib/contrast/components/agent.rb +1 -1
- data/lib/contrast/components/assess.rb +1 -0
- data/lib/contrast/{agent → components}/rule_set.rb +0 -0
- data/lib/contrast/components/scope.rb +1 -1
- data/lib/contrast/components/settings.rb +1 -1
- data/lib/contrast/config/validate.rb +140 -0
- data/lib/contrast/config/yaml_file.rb +129 -0
- data/lib/contrast/extension/assess/exec_trigger.rb +1 -1
- data/lib/contrast/extension/assess/string.rb +4 -3
- data/lib/contrast/tasks/config.rb +7 -118
- data/lib/contrast/utils/middleware_utils.rb +4 -0
- data/lib/contrast.rb +1 -1
- data/ruby-agent.gemspec +6 -3
- metadata +56 -60
- data/lib/contrast/agent/protect/rule/base_service.rb +0 -175
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4f1f41a4e9c4b720867bf41832aceec4b4d4b2e55efafc086f5bf9a14f56401
|
4
|
+
data.tar.gz: 575fbbe0b929cc700daa495403325a27ff90cd92b44f549c9fd44dde7f25ec55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6a321d684f4a220f3eed2cc85ddac8985a4720216beb062d9bc9c75322bbf9d626b96c83f8f0698acdf611fe0ba4dabfa3f908cb6d12a400c3ee05e3d850c05
|
7
|
+
data.tar.gz: 6de14c43bfd6bb54f6fc6da174c1affe91e2712dc6438d69fa6b87404336e8d68691f84339ba756a4a85f5d70ac8b17488a96e786faa77099c5e34963c8e0ffd
|
@@ -9,7 +9,7 @@ module Contrast
|
|
9
9
|
# point of require for this functionality.
|
10
10
|
module Assess
|
11
11
|
require 'contrast/agent/assess/tracker'
|
12
|
-
require 'contrast/agent/module_data'
|
12
|
+
require 'contrast/agent/assess/module_data'
|
13
13
|
require 'contrast/agent/assess/policy/preshift'
|
14
14
|
|
15
15
|
# Dynamic Sources
|
File without changes
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'contrast/agent/patching/policy/method_policy'
|
5
|
+
require 'contrast/components/logger'
|
5
6
|
|
6
7
|
module Contrast
|
7
8
|
module Agent
|
@@ -15,6 +16,8 @@ module Contrast
|
|
15
16
|
READ_TABLE = 'readTable'
|
16
17
|
READ_COLUMN = 'readColumn'
|
17
18
|
class << self
|
19
|
+
include Contrast::Components::Logger::InstanceMethods
|
20
|
+
|
18
21
|
# Given a Class representing a table in a Database and a map of
|
19
22
|
# methods representing columns, generate sources for each method
|
20
23
|
# such that calls to that method will result in a Source Event.
|
@@ -38,6 +38,7 @@ module Contrast
|
|
38
38
|
capitalize!
|
39
39
|
chomp
|
40
40
|
to_s
|
41
|
+
to_str
|
41
42
|
downcase
|
42
43
|
downcase!
|
43
44
|
lstrip
|
@@ -45,7 +46,7 @@ module Contrast
|
|
45
46
|
upcase!
|
46
47
|
upcase
|
47
48
|
].cs__freeze
|
48
|
-
TO_S =
|
49
|
+
TO_S = %w[to_s to_str].cs__freeze
|
49
50
|
|
50
51
|
def initialize policy_hash = {}
|
51
52
|
super(policy_hash)
|
@@ -63,7 +64,7 @@ module Contrast
|
|
63
64
|
# String#to_s => self or string. This method is included here to cover the situations such as
|
64
65
|
# String.to_s.html_safe, where normally the dynamic sources properties get lost. To solve this
|
65
66
|
# we will simply return the original object here.
|
66
|
-
return true if @_use_original_object && policy_hash[JSON_METHOD_NAME]
|
67
|
+
return true if @_use_original_object && TO_S.include?(policy_hash[JSON_METHOD_NAME])
|
67
68
|
|
68
69
|
@_use_original_object &&
|
69
70
|
# Check if method name ends with a (!) bang unless is the to_s method:
|
@@ -92,11 +92,11 @@ module Contrast
|
|
92
92
|
# propagation event.
|
93
93
|
# @param target [Object] the Target to which to propagate.
|
94
94
|
def apply_tags propagation_node, target
|
95
|
-
return unless propagation_node.tags
|
95
|
+
return unless (propagation_tags = propagation_node.tags)
|
96
96
|
return unless (properties = Contrast::Agent::Assess::Tracker.properties(target))
|
97
97
|
|
98
98
|
length = Contrast::Utils::StringUtils.ret_length(target)
|
99
|
-
|
99
|
+
propagation_tags.each do |tag|
|
100
100
|
properties.add_tag(tag, 0...length)
|
101
101
|
end
|
102
102
|
end
|
@@ -50,7 +50,6 @@ module Contrast
|
|
50
50
|
next if known_tainted&.include?(key)
|
51
51
|
next unless (properties = Contrast::Agent::Assess::Tracker.properties!(value))
|
52
52
|
|
53
|
-
# TODO: RUBY-540 handle sanitization, handle nested objects
|
54
53
|
Contrast::Agent::Assess::Policy::PropagationMethod.apply_tags(propagation_node, value)
|
55
54
|
event_data = Contrast::Agent::Assess::Events::EventData.new(propagation_node,
|
56
55
|
value, preshift.object,
|
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
require 'set'
|
5
5
|
require 'contrast/agent/assess/policy/source_validation/source_validation'
|
6
|
-
require 'contrast/agent/excluder'
|
6
|
+
require 'contrast/agent/excluder/excluder'
|
7
7
|
require 'contrast/components/logger'
|
8
8
|
require 'contrast/utils/object_share'
|
9
9
|
require 'contrast/utils/sha256_builder'
|
@@ -2,9 +2,10 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'contrast/agent/assess/policy/trigger_validation/trigger_validation'
|
5
|
-
require 'contrast/agent/excluder'
|
5
|
+
require 'contrast/agent/excluder/excluder'
|
6
6
|
require 'contrast/components/logger'
|
7
7
|
require 'contrast/utils/object_share'
|
8
|
+
require 'contrast/utils/duck_utils'
|
8
9
|
require 'contrast/utils/sha256_builder'
|
9
10
|
require 'contrast/utils/assess/trigger_method_utils'
|
10
11
|
require 'contrast/agent/assess/events/event_data'
|
@@ -99,6 +100,7 @@ module Contrast
|
|
99
100
|
return if excluded_by_input_and_rule?(request, finding, trigger_node.rule_id)
|
100
101
|
|
101
102
|
finding.hash_code = Contrast::Utils::HashDigest.generate_event_hash(finding, source, request)
|
103
|
+
check_for_stored_xss(finding)
|
102
104
|
finding
|
103
105
|
rescue StandardError => e
|
104
106
|
logger.error('Unable to build a finding', e, rule: trigger_node.rule_id, node_id: trigger_node.id)
|
@@ -188,6 +190,39 @@ module Contrast
|
|
188
190
|
def excluded_by_input_and_rule? request, finding, rule_id
|
189
191
|
Contrast::SETTINGS.excluder.assess_excluded_by_input_and_rule?(request, finding, rule_id)
|
190
192
|
end
|
193
|
+
|
194
|
+
# Handles the Stored Xss rule. If a vector is stored in the database
|
195
|
+
def check_for_stored_xss finding
|
196
|
+
return unless finding && finding.rule_id == 'reflected-xss'
|
197
|
+
|
198
|
+
# Check for database tainted event propagation:
|
199
|
+
if finding.events.select { |event| event.reportable_tags.include?('DATABASE_WRITE') }.
|
200
|
+
any? && !Contrast::ASSESS.disabled_rules.include?('stored-xss')
|
201
|
+
|
202
|
+
# Override 'reflected-xss' => 'stored-xss'
|
203
|
+
finding.instance_variable_set(:@rule_id, 'stored-xss')
|
204
|
+
extract_dynamic_source_info(finding)
|
205
|
+
finding
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def extract_dynamic_source_info finding
|
210
|
+
return unless finding
|
211
|
+
|
212
|
+
creation_events = finding.events.select { |e| e.action == :CREATION }
|
213
|
+
source_event_policy = creation_events[0].policy_node if creation_events.any?
|
214
|
+
properties = source_event_policy.properties if source_event_policy
|
215
|
+
# Properties example:
|
216
|
+
# => {"dynamic_source_id"=>"Assess:Source:Comment#message",
|
217
|
+
# "dynamic_source_name"=>"Comment.message",
|
218
|
+
# "readTable"=>"Comment",
|
219
|
+
# "readColumn"=>:message,
|
220
|
+
# "writeDateTimeUtc"=>1675087341948,
|
221
|
+
# "writeRequestUrl"=>"/comments"}
|
222
|
+
return if Contrast::Utils::DuckUtils.empty_duck?(properties)
|
223
|
+
|
224
|
+
finding.instance_variable_set(:@properties, finding.properties.merge(properties))
|
225
|
+
end
|
191
226
|
end
|
192
227
|
end
|
193
228
|
end
|
@@ -7,7 +7,7 @@ module Contrast
|
|
7
7
|
module Policy
|
8
8
|
module TriggerValidation
|
9
9
|
# Validator used to assert a REDOS finding is actually vulnerable
|
10
|
-
# before serializing that finding as a
|
10
|
+
# before serializing that finding as a Event to report to the TeamServer.
|
11
11
|
module REDOSValidator
|
12
12
|
RULE_NAME = 'redos'
|
13
13
|
# If Regexp is set to Float::Infinite this is the maximum number it will receive
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -54,6 +54,7 @@ module Contrast
|
|
54
54
|
# @return [Hash]
|
55
55
|
def active_record_config
|
56
56
|
return @_active_record_config if instance_variable_defined?(:@_active_record_config)
|
57
|
+
return unless defined?(ActiveRecord) && defined?(ActiveRecord::Base)
|
57
58
|
|
58
59
|
@_active_record_config = if ActiveRecord::Base.cs__respond_to?(:connection_db_config)
|
59
60
|
ActiveRecord::Base.connection_db_config
|
File without changes
|
@@ -10,9 +10,9 @@ require 'contrast/utils/object_share'
|
|
10
10
|
require 'contrast/components/logger'
|
11
11
|
require 'contrast/components/scope'
|
12
12
|
require 'contrast/utils/heap_dump_util'
|
13
|
-
require 'contrast/agent/telemetry'
|
14
|
-
require 'contrast/agent/request_handler'
|
15
|
-
require 'contrast/agent/static_analysis'
|
13
|
+
require 'contrast/agent/telemetry/telemetry'
|
14
|
+
require 'contrast/agent/request/request_handler'
|
15
|
+
require 'contrast/agent/middleware/static_analysis'
|
16
16
|
require 'contrast/agent/telemetry/startup_metrics_event'
|
17
17
|
require 'contrast/agent/protect/input_analyzer/input_analyzer'
|
18
18
|
require 'contrast/utils/middleware_utils'
|
File without changes
|
@@ -4,18 +4,18 @@
|
|
4
4
|
require 'contrast/agent/reporting/input_analysis/input_type'
|
5
5
|
require 'contrast/agent/reporting/input_analysis/score_level'
|
6
6
|
require 'contrast/agent/reporting/input_analysis/input_analysis'
|
7
|
-
require 'contrast/agent/protect/rule/bot_blocker'
|
7
|
+
require 'contrast/agent/protect/rule/bot_blocker/bot_blocker'
|
8
8
|
require 'contrast/agent/protect/rule/bot_blocker/bot_blocker_input_classification'
|
9
9
|
require 'contrast/agent/protect/rule/cmdi/cmdi_input_classification'
|
10
|
-
require 'contrast/agent/protect/rule/no_sqli'
|
10
|
+
require 'contrast/agent/protect/rule/no_sqli/no_sqli'
|
11
11
|
require 'contrast/agent/protect/rule/no_sqli/no_sqli_input_classification'
|
12
12
|
require 'contrast/agent/protect/rule/sqli/sqli_input_classification'
|
13
13
|
require 'contrast/agent/protect/rule/unsafe_file_upload/unsafe_file_upload_input_classification'
|
14
|
-
require 'contrast/agent/protect/rule/unsafe_file_upload'
|
15
|
-
require 'contrast/agent/protect/rule/path_traversal'
|
14
|
+
require 'contrast/agent/protect/rule/unsafe_file_upload/unsafe_file_upload'
|
15
|
+
require 'contrast/agent/protect/rule/path_traversal/path_traversal'
|
16
16
|
require 'contrast/agent/protect/rule/path_traversal/path_traversal_input_classification'
|
17
17
|
require 'contrast/agent/protect/rule/xss/reflected_xss_input_classification'
|
18
|
-
require 'contrast/agent/protect/rule/xss'
|
18
|
+
require 'contrast/agent/protect/rule/xss/xss'
|
19
19
|
require 'contrast/components/logger'
|
20
20
|
require 'contrast/utils/object_share'
|
21
21
|
require 'json'
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Copyright (c) 2023 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/agent/worker_thread'
|
4
|
+
require 'contrast/agent/thread/worker_thread'
|
5
5
|
require 'contrast/agent/reporting/input_analysis/input_analysis_result'
|
6
6
|
require 'contrast/agent/reporting/input_analysis/score_level'
|
7
7
|
require 'contrast/agent/reporting/reporting_events/application_activity'
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Copyright (c) 2023 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/agent/protect/rule/cmd_injection'
|
4
|
+
require 'contrast/agent/protect/rule/cmdi/cmd_injection'
|
5
5
|
require 'contrast/agent/protect/policy/applies_deserialization_rule'
|
6
6
|
require 'contrast/agent/protect/policy/rule_applicator'
|
7
7
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Copyright (c) 2023 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/agent/protect/rule/deserialization'
|
4
|
+
require 'contrast/agent/protect/rule/deserialization/deserialization'
|
5
5
|
require 'contrast/agent/protect/policy/rule_applicator'
|
6
6
|
|
7
7
|
module Contrast
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Copyright (c) 2023 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/agent/protect/rule/no_sqli'
|
4
|
+
require 'contrast/agent/protect/rule/no_sqli/no_sqli'
|
5
5
|
require 'contrast/agent/protect/policy/rule_applicator'
|
6
6
|
|
7
7
|
module Contrast
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Copyright (c) 2023 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/agent/protect/rule/path_traversal'
|
4
|
+
require 'contrast/agent/protect/rule/path_traversal/path_traversal'
|
5
5
|
require 'contrast/agent/protect/rule/path_traversal/path_traversal_semantic_security_bypass'
|
6
6
|
require 'contrast/agent/protect/policy/rule_applicator'
|
7
7
|
require 'contrast/utils/object_share'
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Copyright (c) 2023 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/agent/protect/rule/sqli'
|
4
|
+
require 'contrast/agent/protect/rule/sqli/sqli'
|
5
5
|
require 'contrast/agent/protect/policy/rule_applicator'
|
6
6
|
|
7
7
|
module Contrast
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Copyright (c) 2023 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/agent/protect/rule/xxe'
|
4
|
+
require 'contrast/agent/protect/rule/xxe/xxe'
|
5
5
|
require 'contrast/agent/protect/policy/rule_applicator'
|
6
6
|
require 'contrast/utils/object_share'
|
7
7
|
|