contrast-agent 7.2.0 → 7.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/contrast/agent/protect/input_analyzer/input_analyzer.rb +62 -23
- data/lib/contrast/agent/protect/input_analyzer/worth_watching_analyzer.rb +37 -4
- data/lib/contrast/agent/protect/rule/base.rb +5 -1
- data/lib/contrast/agent/protect/rule/bot_blocker/bot_blocker_input_classification.rb +27 -11
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_base_rule.rb +0 -1
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_input_classification.rb +2 -2
- data/lib/contrast/agent/protect/rule/input_classification/base.rb +191 -0
- data/lib/contrast/agent/protect/rule/input_classification/base64_statistic.rb +71 -0
- data/lib/contrast/agent/protect/rule/input_classification/cached_result.rb +37 -0
- data/lib/contrast/agent/protect/rule/input_classification/encoding.rb +109 -0
- data/lib/contrast/agent/protect/rule/input_classification/encoding_rates.rb +47 -0
- data/lib/contrast/agent/protect/rule/input_classification/extendable.rb +80 -0
- data/lib/contrast/agent/protect/rule/input_classification/lru_cache.rb +198 -0
- data/lib/contrast/agent/protect/rule/input_classification/match_rates.rb +66 -0
- data/lib/contrast/agent/protect/rule/input_classification/rates.rb +53 -0
- data/lib/contrast/agent/protect/rule/input_classification/statistics.rb +115 -0
- data/lib/contrast/agent/protect/rule/input_classification/utils.rb +23 -0
- data/lib/contrast/agent/protect/rule/no_sqli/no_sqli_input_classification.rb +17 -7
- data/lib/contrast/agent/protect/rule/path_traversal/path_traversal_input_classification.rb +18 -15
- data/lib/contrast/agent/protect/rule/sqli/sqli_input_classification.rb +2 -2
- data/lib/contrast/agent/protect/rule/unsafe_file_upload/unsafe_file_upload_input_classification.rb +18 -15
- data/lib/contrast/agent/protect/rule/xss/reflected_xss_input_classification.rb +19 -17
- data/lib/contrast/agent/reporting/attack_result/attack_result.rb +6 -0
- data/lib/contrast/agent/reporting/input_analysis/input_analysis.rb +2 -7
- data/lib/contrast/agent/reporting/input_analysis/input_analysis_result.rb +11 -0
- data/lib/contrast/agent/reporting/input_analysis/input_type.rb +33 -1
- data/lib/contrast/agent/reporting/masker/masker_utils.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_events/application_defend_activity.rb +1 -0
- data/lib/contrast/agent/reporting/reporting_events/application_defend_attacker_activity.rb +1 -0
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +1 -1
- data/lib/contrast/agent/telemetry/base.rb +28 -2
- data/lib/contrast/agent/telemetry/base64_hash.rb +55 -0
- data/lib/contrast/agent/telemetry/cache_hash.rb +55 -0
- data/lib/contrast/agent/telemetry/client.rb +10 -2
- data/lib/contrast/agent/telemetry/{hash.rb → exception_hash.rb} +1 -1
- data/lib/contrast/agent/telemetry/input_analysis_cache_event.rb +27 -0
- data/lib/contrast/agent/telemetry/input_analysis_encoding_event.rb +26 -0
- data/lib/contrast/agent/telemetry/input_analysis_event.rb +91 -0
- data/lib/contrast/agent/telemetry/metric_event.rb +12 -0
- data/lib/contrast/agent/telemetry/startup_metrics_event.rb +0 -8
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/components/config.rb +4 -4
- data/lib/contrast/components/protect.rb +11 -1
- data/lib/contrast/components/sampling.rb +15 -10
- data/lib/contrast/config/diagnostics/environment_variables.rb +3 -1
- data/lib/contrast/config/yaml_file.rb +8 -0
- data/lib/contrast/framework/rails/support.rb +3 -0
- data/lib/contrast/utils/assess/event_limit_utils.rb +13 -13
- data/lib/contrast/utils/metrics_hash.rb +1 -1
- data/lib/contrast/utils/object_share.rb +2 -1
- data/lib/contrast/utils/response_utils.rb +12 -0
- data/lib/contrast/utils/timer.rb +2 -0
- data/lib/contrast.rb +9 -2
- data/ruby-agent.gemspec +1 -1
- metadata +21 -6
- data/lib/contrast/utils/input_classification_base.rb +0 -169
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: contrast-agent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.
|
4
|
+
version: 7.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- galen.palmer@contrastsecurity.com
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: exe
|
15
15
|
cert_chain: []
|
16
|
-
date: 2023-
|
16
|
+
date: 2023-07-26 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: bundler
|
@@ -669,14 +669,14 @@ dependencies:
|
|
669
669
|
requirements:
|
670
670
|
- - '='
|
671
671
|
- !ruby/object:Gem::Version
|
672
|
-
version: 1.1.
|
672
|
+
version: 1.1.1
|
673
673
|
type: :runtime
|
674
674
|
prerelease: false
|
675
675
|
version_requirements: !ruby/object:Gem::Requirement
|
676
676
|
requirements:
|
677
677
|
- - '='
|
678
678
|
- !ruby/object:Gem::Version
|
679
|
-
version: 1.1.
|
679
|
+
version: 1.1.1
|
680
680
|
description: This gem instantiates a Rack middleware for rack-based web applications
|
681
681
|
in order to provide Interactive Application Security Testing and Protection.
|
682
682
|
email:
|
@@ -1023,6 +1023,17 @@ files:
|
|
1023
1023
|
- lib/contrast/agent/protect/rule/cmdi/cmdi_input_classification.rb
|
1024
1024
|
- lib/contrast/agent/protect/rule/default_scanner.rb
|
1025
1025
|
- lib/contrast/agent/protect/rule/deserialization/deserialization.rb
|
1026
|
+
- lib/contrast/agent/protect/rule/input_classification/base.rb
|
1027
|
+
- lib/contrast/agent/protect/rule/input_classification/base64_statistic.rb
|
1028
|
+
- lib/contrast/agent/protect/rule/input_classification/cached_result.rb
|
1029
|
+
- lib/contrast/agent/protect/rule/input_classification/encoding.rb
|
1030
|
+
- lib/contrast/agent/protect/rule/input_classification/encoding_rates.rb
|
1031
|
+
- lib/contrast/agent/protect/rule/input_classification/extendable.rb
|
1032
|
+
- lib/contrast/agent/protect/rule/input_classification/lru_cache.rb
|
1033
|
+
- lib/contrast/agent/protect/rule/input_classification/match_rates.rb
|
1034
|
+
- lib/contrast/agent/protect/rule/input_classification/rates.rb
|
1035
|
+
- lib/contrast/agent/protect/rule/input_classification/statistics.rb
|
1036
|
+
- lib/contrast/agent/protect/rule/input_classification/utils.rb
|
1026
1037
|
- lib/contrast/agent/protect/rule/no_sqli/mongo_no_sql_scanner.rb
|
1027
1038
|
- lib/contrast/agent/protect/rule/no_sqli/no_sqli.rb
|
1028
1039
|
- lib/contrast/agent/protect/rule/no_sqli/no_sqli_input_classification.rb
|
@@ -1176,6 +1187,8 @@ files:
|
|
1176
1187
|
- lib/contrast/agent/response/response.rb
|
1177
1188
|
- lib/contrast/agent/scope/scope.rb
|
1178
1189
|
- lib/contrast/agent/telemetry/base.rb
|
1190
|
+
- lib/contrast/agent/telemetry/base64_hash.rb
|
1191
|
+
- lib/contrast/agent/telemetry/cache_hash.rb
|
1179
1192
|
- lib/contrast/agent/telemetry/client.rb
|
1180
1193
|
- lib/contrast/agent/telemetry/event.rb
|
1181
1194
|
- lib/contrast/agent/telemetry/exception.rb
|
@@ -1185,8 +1198,11 @@ files:
|
|
1185
1198
|
- lib/contrast/agent/telemetry/exception/message_exception.rb
|
1186
1199
|
- lib/contrast/agent/telemetry/exception/obfuscate.rb
|
1187
1200
|
- lib/contrast/agent/telemetry/exception/stack_frame.rb
|
1188
|
-
- lib/contrast/agent/telemetry/
|
1201
|
+
- lib/contrast/agent/telemetry/exception_hash.rb
|
1189
1202
|
- lib/contrast/agent/telemetry/identifier.rb
|
1203
|
+
- lib/contrast/agent/telemetry/input_analysis_cache_event.rb
|
1204
|
+
- lib/contrast/agent/telemetry/input_analysis_encoding_event.rb
|
1205
|
+
- lib/contrast/agent/telemetry/input_analysis_event.rb
|
1190
1206
|
- lib/contrast/agent/telemetry/metric_event.rb
|
1191
1207
|
- lib/contrast/agent/telemetry/startup_metrics_event.rb
|
1192
1208
|
- lib/contrast/agent/telemetry/telemetry.rb
|
@@ -1310,7 +1326,6 @@ files:
|
|
1310
1326
|
- lib/contrast/utils/hash_utils.rb
|
1311
1327
|
- lib/contrast/utils/head_dump_utils_extend.rb
|
1312
1328
|
- lib/contrast/utils/heap_dump_util.rb
|
1313
|
-
- lib/contrast/utils/input_classification_base.rb
|
1314
1329
|
- lib/contrast/utils/invalid_configuration_util.rb
|
1315
1330
|
- lib/contrast/utils/io_util.rb
|
1316
1331
|
- lib/contrast/utils/job_servers_running.rb
|
@@ -1,169 +0,0 @@
|
|
1
|
-
# Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require 'contrast/utils/object_share'
|
5
|
-
require 'contrast/agent/reporting/input_analysis/input_type'
|
6
|
-
require 'contrast/agent/reporting/input_analysis/score_level'
|
7
|
-
require 'contrast/agent/protect/input_analyzer/input_analyzer'
|
8
|
-
require 'contrast/components/logger'
|
9
|
-
|
10
|
-
module Contrast
|
11
|
-
module Agent
|
12
|
-
module Protect
|
13
|
-
module Rule
|
14
|
-
# This module will include all the similar information for all input classifications
|
15
|
-
# between different rules
|
16
|
-
module InputClassificationBase
|
17
|
-
UNKNOWN_KEY = 'unknown'
|
18
|
-
THRESHOLD = 90.cs__freeze
|
19
|
-
WORTHWATCHING_THRESHOLD = 10.cs__freeze
|
20
|
-
include Contrast::Agent::Reporting::InputType
|
21
|
-
include Contrast::Agent::Reporting::ScoreLevel
|
22
|
-
include Contrast::Components::Logger::InstanceMethods
|
23
|
-
|
24
|
-
KEYS_NEEDED = [COOKIE_VALUE, PARAMETER_VALUE, JSON_VALUE, MULTIPART_VALUE, XML_VALUE, DWR_VALUE].cs__freeze
|
25
|
-
|
26
|
-
# Input Classification stage is done to determine if an user input is
|
27
|
-
# DEFINITEATTACK or to be ignored.
|
28
|
-
#
|
29
|
-
# @param rule_id [String] Name of the protect rule.
|
30
|
-
# @param input_type [Symbol, Contrast::Agent::Reporting::InputType] The type of the user input.
|
31
|
-
# @param value [String, Array<String>] the value of the input.
|
32
|
-
# @param input_analysis [Contrast::Agent::Reporting::InputAnalysis] Holds all the results from the
|
33
|
-
# agent analysis from the current
|
34
|
-
# Request.
|
35
|
-
# @return ia [Contrast::Agent::Reporting::InputAnalysis, nil] with updated results.
|
36
|
-
def classify rule_id, input_type, value, input_analysis
|
37
|
-
return unless (rule = Contrast::PROTECT.rule(rule_id))
|
38
|
-
return unless rule.applicable_user_inputs.include?(input_type)
|
39
|
-
return unless input_analysis.request
|
40
|
-
|
41
|
-
Array(value).each do |val|
|
42
|
-
Array(val).each do |v|
|
43
|
-
next unless v
|
44
|
-
|
45
|
-
result = create_new_input_result(input_analysis.request, rule.rule_name, input_type, v)
|
46
|
-
append_result(input_analysis, result)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
input_analysis
|
51
|
-
rescue StandardError => e
|
52
|
-
logger.debug("An Error was recorded in the input classification of the #{ rule_id }")
|
53
|
-
logger.debug(e)
|
54
|
-
nil
|
55
|
-
end
|
56
|
-
|
57
|
-
# Creates new isntance of InputAnalysisResult with basic info.
|
58
|
-
#
|
59
|
-
# @param rule_id [String] The name of the Protect Rule.
|
60
|
-
# @param input_type [Contrast::Agent::Reporting::InputType] The type of the user input.
|
61
|
-
# @param value [String, Array<String>] the value of the input.
|
62
|
-
# @param path [String] the path of the current request context.
|
63
|
-
#
|
64
|
-
# @return res [Contrast::Agent::Reporting::InputAnalysisResult]
|
65
|
-
def new_ia_result rule_id, input_type, path, value = nil
|
66
|
-
res = Contrast::Agent::Reporting::InputAnalysisResult.new
|
67
|
-
res.rule_id = rule_id
|
68
|
-
res.input_type = input_type
|
69
|
-
res.path = path
|
70
|
-
res.value = value
|
71
|
-
res
|
72
|
-
end
|
73
|
-
|
74
|
-
# This methods checks if input is value that matches a key in the input.
|
75
|
-
#
|
76
|
-
# @param request [Contrast::Agent::Request] the current request context.
|
77
|
-
# @param result [Contrast::Agent::Reporting::InputAnalysisResult] result to be updated.
|
78
|
-
# @param input_type [Contrast::Agent::Reporting::InputType] The type of the user input.
|
79
|
-
# @param value [String, Array<String>] the value of the input.
|
80
|
-
#
|
81
|
-
# @return result [Contrast::Agent::Reporting::InputAnalysisResult] updated with key result.
|
82
|
-
def add_needed_key request, result, input_type, value
|
83
|
-
case input_type
|
84
|
-
when COOKIE_VALUE
|
85
|
-
result.key = request.cookies.key(value)
|
86
|
-
when PARAMETER_VALUE, URL_PARAMETER
|
87
|
-
result.key = request.parameters.key(value)
|
88
|
-
when HEADER
|
89
|
-
result.key = request.headers.key(value)
|
90
|
-
when UNKNOWN
|
91
|
-
result.key = UNKNOWN_KEY
|
92
|
-
else
|
93
|
-
result.key
|
94
|
-
end
|
95
|
-
rescue StandardError => e
|
96
|
-
logger.warn('Could not find proper key for input traced value', message: e)
|
97
|
-
end
|
98
|
-
|
99
|
-
# Some input types are not yet supported from the AgentLib.
|
100
|
-
# This will convert the type to the closet possible if viable,
|
101
|
-
# so that the input tracing could be done.
|
102
|
-
#
|
103
|
-
# @param input_type [Contrast::Agent::Reporting::InputType] The type of the user input.
|
104
|
-
# @return [Integer<Contrast::AgentLib::Interface::INPUT_SET>]
|
105
|
-
def convert_input_type input_type
|
106
|
-
case input_type
|
107
|
-
when URI, URL_PARAMETER
|
108
|
-
Contrast::AGENT_LIB.input_set[:URI_PATH]
|
109
|
-
when BODY, DWR_VALUE, SOCKET, UNDEFINED_TYPE, UNKNOWN, REQUEST, QUERYSTRING
|
110
|
-
Contrast::AGENT_LIB.input_set[:PARAMETER_VALUE]
|
111
|
-
when HEADER
|
112
|
-
Contrast::AGENT_LIB.input_set[:HEADER_VALUE]
|
113
|
-
when MULTIPART_VALUE, MULTIPART_FIELD_NAME
|
114
|
-
Contrast::AGENT_LIB.input_set[:MULTIPART_NAME]
|
115
|
-
when JSON_ARRAYED_VALUE
|
116
|
-
Contrast::AGENT_LIB.input_set[:JSON_KEY]
|
117
|
-
when PARAMETER_NAME
|
118
|
-
Contrast::AGENT_LIB.input_set[:PARAMETER_KEY]
|
119
|
-
else
|
120
|
-
Contrast::AGENT_LIB.input_set[input_type]
|
121
|
-
end
|
122
|
-
rescue StandardError => e
|
123
|
-
logger.debug('Protect Input classification could not determine input type, falling back to default',
|
124
|
-
error: e)
|
125
|
-
Contrast::AGENT_LIB.input_set[:PARAMETER_VALUE]
|
126
|
-
end
|
127
|
-
|
128
|
-
private
|
129
|
-
|
130
|
-
# This methods checks if input is tagged WORTHWATCHING or IGNORE matches value with it's
|
131
|
-
# key if needed and Creates new instance of InputAnalysisResult.
|
132
|
-
#
|
133
|
-
# @param request [Contrast::Agent::Request] the current request context.
|
134
|
-
# @param rule_id [String] The name of the Protect Rule.
|
135
|
-
# @param input_type [Contrast::Agent::Reporting::InputType] The type of the user input.
|
136
|
-
# @param value [String, Array<String>] the value of the input.
|
137
|
-
#
|
138
|
-
# @return res [Contrast::Agent::Reporting::InputAnalysisResult, nil]
|
139
|
-
def create_new_input_result request, rule_id, input_type, value
|
140
|
-
return unless Contrast::AGENT_LIB
|
141
|
-
|
142
|
-
input_eval = Contrast::AGENT_LIB.eval_input(value,
|
143
|
-
convert_input_type(input_type),
|
144
|
-
Contrast::AGENT_LIB.rule_set[rule_id],
|
145
|
-
Contrast::AGENT_LIB.eval_option[:PREFER_WORTH_WATCHING])
|
146
|
-
|
147
|
-
ia_result = new_ia_result(rule_id, input_type, request.path, value)
|
148
|
-
score = input_eval&.score || 0
|
149
|
-
if score >= WORTHWATCHING_THRESHOLD
|
150
|
-
ia_result.score_level = WORTHWATCHING
|
151
|
-
ia_result.ids << self::WORTHWATCHING_MATCH
|
152
|
-
else
|
153
|
-
ia_result.score_level = IGNORE
|
154
|
-
return
|
155
|
-
end
|
156
|
-
|
157
|
-
add_needed_key(request, ia_result, input_type, value) if KEYS_NEEDED.include?(input_type)
|
158
|
-
ia_result
|
159
|
-
end
|
160
|
-
|
161
|
-
def append_result ia_analysis, result
|
162
|
-
ia_analysis.results << result if result
|
163
|
-
ia_analysis
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|