contrast-agent 7.2.0 → 7.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/lib/contrast/agent/protect/input_analyzer/input_analyzer.rb +62 -23
  3. data/lib/contrast/agent/protect/input_analyzer/worth_watching_analyzer.rb +37 -4
  4. data/lib/contrast/agent/protect/rule/base.rb +5 -1
  5. data/lib/contrast/agent/protect/rule/bot_blocker/bot_blocker_input_classification.rb +27 -11
  6. data/lib/contrast/agent/protect/rule/cmdi/cmdi_base_rule.rb +0 -1
  7. data/lib/contrast/agent/protect/rule/cmdi/cmdi_input_classification.rb +2 -2
  8. data/lib/contrast/agent/protect/rule/input_classification/base.rb +191 -0
  9. data/lib/contrast/agent/protect/rule/input_classification/base64_statistic.rb +71 -0
  10. data/lib/contrast/agent/protect/rule/input_classification/cached_result.rb +37 -0
  11. data/lib/contrast/agent/protect/rule/input_classification/encoding.rb +109 -0
  12. data/lib/contrast/agent/protect/rule/input_classification/encoding_rates.rb +47 -0
  13. data/lib/contrast/agent/protect/rule/input_classification/extendable.rb +80 -0
  14. data/lib/contrast/agent/protect/rule/input_classification/lru_cache.rb +198 -0
  15. data/lib/contrast/agent/protect/rule/input_classification/match_rates.rb +66 -0
  16. data/lib/contrast/agent/protect/rule/input_classification/rates.rb +53 -0
  17. data/lib/contrast/agent/protect/rule/input_classification/statistics.rb +115 -0
  18. data/lib/contrast/agent/protect/rule/input_classification/utils.rb +23 -0
  19. data/lib/contrast/agent/protect/rule/no_sqli/no_sqli_input_classification.rb +17 -7
  20. data/lib/contrast/agent/protect/rule/path_traversal/path_traversal_input_classification.rb +18 -15
  21. data/lib/contrast/agent/protect/rule/sqli/sqli_input_classification.rb +2 -2
  22. data/lib/contrast/agent/protect/rule/unsafe_file_upload/unsafe_file_upload_input_classification.rb +18 -15
  23. data/lib/contrast/agent/protect/rule/xss/reflected_xss_input_classification.rb +19 -17
  24. data/lib/contrast/agent/reporting/attack_result/attack_result.rb +6 -0
  25. data/lib/contrast/agent/reporting/input_analysis/input_analysis.rb +2 -7
  26. data/lib/contrast/agent/reporting/input_analysis/input_analysis_result.rb +11 -0
  27. data/lib/contrast/agent/reporting/input_analysis/input_type.rb +33 -1
  28. data/lib/contrast/agent/reporting/masker/masker_utils.rb +1 -1
  29. data/lib/contrast/agent/reporting/reporting_events/application_defend_activity.rb +1 -0
  30. data/lib/contrast/agent/reporting/reporting_events/application_defend_attacker_activity.rb +1 -0
  31. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +1 -1
  32. data/lib/contrast/agent/telemetry/base.rb +28 -2
  33. data/lib/contrast/agent/telemetry/base64_hash.rb +55 -0
  34. data/lib/contrast/agent/telemetry/cache_hash.rb +55 -0
  35. data/lib/contrast/agent/telemetry/client.rb +10 -2
  36. data/lib/contrast/agent/telemetry/{hash.rb → exception_hash.rb} +1 -1
  37. data/lib/contrast/agent/telemetry/input_analysis_cache_event.rb +27 -0
  38. data/lib/contrast/agent/telemetry/input_analysis_encoding_event.rb +26 -0
  39. data/lib/contrast/agent/telemetry/input_analysis_event.rb +91 -0
  40. data/lib/contrast/agent/telemetry/metric_event.rb +12 -0
  41. data/lib/contrast/agent/telemetry/startup_metrics_event.rb +0 -8
  42. data/lib/contrast/agent/version.rb +1 -1
  43. data/lib/contrast/components/config.rb +4 -4
  44. data/lib/contrast/components/protect.rb +11 -1
  45. data/lib/contrast/components/sampling.rb +15 -10
  46. data/lib/contrast/config/diagnostics/environment_variables.rb +3 -1
  47. data/lib/contrast/config/yaml_file.rb +8 -0
  48. data/lib/contrast/framework/rails/support.rb +3 -0
  49. data/lib/contrast/utils/assess/event_limit_utils.rb +13 -13
  50. data/lib/contrast/utils/metrics_hash.rb +1 -1
  51. data/lib/contrast/utils/object_share.rb +2 -1
  52. data/lib/contrast/utils/response_utils.rb +12 -0
  53. data/lib/contrast/utils/timer.rb +2 -0
  54. data/lib/contrast.rb +9 -2
  55. data/ruby-agent.gemspec +1 -1
  56. metadata +21 -6
  57. 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.2.0
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-05-31 00:00:00.000000000 Z
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.0
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.0
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/hash.rb
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