contrast-agent 6.1.1 → 6.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) hide show
  1. checksums.yaml +4 -4
  2. data/ext/cs__assess_basic_object/cs__assess_basic_object.c +7 -5
  3. data/ext/cs__assess_kernel/cs__assess_kernel.c +14 -3
  4. data/ext/cs__assess_kernel/cs__assess_kernel.h +2 -0
  5. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +10 -3
  6. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.h +2 -1
  7. data/ext/cs__assess_regexp/cs__assess_regexp.c +9 -7
  8. data/ext/{cs__assess_string_interpolation26/cs__assess_string_interpolation26.c → cs__assess_string_interpolation/cs__assess_string_interpolation.c} +14 -3
  9. data/ext/{cs__assess_string_interpolation26/cs__assess_string_interpolation26.h → cs__assess_string_interpolation/cs__assess_string_interpolation.h} +1 -1
  10. data/ext/{cs__assess_string_interpolation26 → cs__assess_string_interpolation}/extconf.rb +0 -0
  11. data/ext/cs__common/cs__common.c +5 -4
  12. data/ext/cs__contrast_patch/cs__contrast_patch.c +3 -10
  13. data/lib/contrast/agent/assess/events/source_event.rb +16 -12
  14. data/lib/contrast/agent/assess/policy/policy_node.rb +6 -0
  15. data/lib/contrast/agent/assess/policy/propagation_method.rb +3 -39
  16. data/lib/contrast/agent/assess/policy/propagation_node.rb +8 -0
  17. data/lib/contrast/agent/assess/policy/propagator/base.rb +2 -0
  18. data/lib/contrast/agent/assess/policy/source_method.rb +2 -47
  19. data/lib/contrast/agent/assess/policy/source_node.rb +1 -0
  20. data/lib/contrast/agent/assess/policy/trigger_node.rb +8 -0
  21. data/lib/contrast/agent/assess/property/evented.rb +4 -18
  22. data/lib/contrast/agent/assess/tag.rb +19 -0
  23. data/lib/contrast/agent/at_exit_hook.rb +9 -8
  24. data/lib/contrast/agent/inventory/database_config.rb +18 -7
  25. data/lib/contrast/agent/inventory/dependency_analysis.rb +3 -2
  26. data/lib/contrast/agent/inventory/dependency_usage_analysis.rb +13 -9
  27. data/lib/contrast/agent/middleware.rb +4 -0
  28. data/lib/contrast/agent/patching/policy/after_load_patcher.rb +27 -2
  29. data/lib/contrast/agent/patching/policy/policy.rb +5 -0
  30. data/lib/contrast/agent/patching/policy/policy_node.rb +6 -0
  31. data/lib/contrast/agent/patching/policy/trigger_node.rb +3 -0
  32. data/lib/contrast/agent/protect/policy/applies_deserialization_rule.rb +3 -4
  33. data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +1 -0
  34. data/lib/contrast/agent/protect/policy/rule_applicator.rb +2 -2
  35. data/lib/contrast/agent/protect/rule/base.rb +1 -0
  36. data/lib/contrast/agent/protect/rule/no_sqli.rb +2 -0
  37. data/lib/contrast/agent/protect/rule/xss.rb +4 -0
  38. data/lib/contrast/agent/reporting/reporter.rb +33 -17
  39. data/lib/contrast/agent/reporting/reporter_heartbeat.rb +21 -15
  40. data/lib/contrast/agent/reporting/reporting_events/application_inventory.rb +3 -18
  41. data/lib/contrast/agent/reporting/reporting_events/application_update.rb +5 -24
  42. data/lib/contrast/agent/reporting/reporting_events/architecture_component.rb +8 -1
  43. data/lib/contrast/agent/reporting/reporting_events/discovered_route.rb +83 -16
  44. data/lib/contrast/agent/reporting/reporting_events/finding.rb +9 -3
  45. data/lib/contrast/agent/reporting/reporting_events/finding_event.rb +10 -1
  46. data/lib/contrast/agent/reporting/reporting_events/finding_event_object.rb +11 -1
  47. data/lib/contrast/agent/reporting/reporting_events/finding_event_parent_object.rb +11 -1
  48. data/lib/contrast/agent/reporting/reporting_events/finding_event_property.rb +12 -1
  49. data/lib/contrast/agent/reporting/reporting_events/finding_event_signature.rb +10 -1
  50. data/lib/contrast/agent/reporting/reporting_events/finding_event_source.rb +11 -1
  51. data/lib/contrast/agent/reporting/reporting_events/finding_event_stack.rb +11 -1
  52. data/lib/contrast/agent/reporting/reporting_events/finding_event_taint_range.rb +11 -1
  53. data/lib/contrast/agent/reporting/reporting_events/finding_request.rb +11 -1
  54. data/lib/contrast/agent/reporting/reporting_events/library_discovery.rb +29 -32
  55. data/lib/contrast/agent/reporting/reporting_events/library_usage_observation.rb +18 -20
  56. data/lib/contrast/agent/reporting/reporting_events/observed_library_usage.rb +11 -24
  57. data/lib/contrast/agent/reporting/reporting_events/observed_route.rb +13 -6
  58. data/lib/contrast/agent/reporting/reporting_events/preflight_message.rb +10 -4
  59. data/lib/contrast/agent/reporting/reporting_events/reporting_event.rb +10 -4
  60. data/lib/contrast/agent/reporting/reporting_events/route_coverage.rb +9 -0
  61. data/lib/contrast/agent/reporting/reporting_events/route_discovery.rb +10 -1
  62. data/lib/contrast/agent/reporting/reporting_events/route_discovery_observation.rb +11 -4
  63. data/lib/contrast/agent/reporting/reporting_events/server_activity.rb +0 -8
  64. data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +2 -6
  65. data/lib/contrast/agent/reporting/reporting_utilities/dtm_message.rb +0 -32
  66. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +1 -4
  67. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +1 -11
  68. data/lib/contrast/agent/reporting/reporting_utilities/response.rb +60 -2
  69. data/lib/contrast/agent/reporting/reporting_utilities/response_extractor.rb +32 -10
  70. data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +1 -1
  71. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +58 -26
  72. data/lib/contrast/agent/reporting/settings/application_settings.rb +8 -23
  73. data/lib/contrast/agent/reporting/settings/assess_server_feature.rb +27 -33
  74. data/lib/contrast/agent/reporting/settings/bot_blocker.rb +68 -0
  75. data/lib/contrast/agent/reporting/settings/code_exclusion.rb +27 -0
  76. data/lib/contrast/agent/reporting/settings/exclusion_base.rb +33 -0
  77. data/lib/contrast/agent/reporting/settings/exclusions.rb +39 -57
  78. data/lib/contrast/agent/reporting/settings/helpers.rb +56 -0
  79. data/lib/contrast/agent/reporting/settings/input_exclusion.rb +37 -0
  80. data/lib/contrast/agent/reporting/settings/ip_filter.rb +35 -0
  81. data/lib/contrast/agent/reporting/settings/keyword.rb +74 -0
  82. data/lib/contrast/agent/reporting/settings/log_enhancer.rb +65 -0
  83. data/lib/contrast/agent/reporting/settings/protect.rb +4 -2
  84. data/lib/contrast/agent/reporting/settings/protect_server_feature.rb +62 -115
  85. data/lib/contrast/agent/reporting/settings/reaction.rb +11 -2
  86. data/lib/contrast/agent/reporting/settings/rule_definition.rb +63 -0
  87. data/lib/contrast/agent/reporting/settings/sampling.rb +10 -0
  88. data/lib/contrast/agent/reporting/settings/sanitizer.rb +38 -0
  89. data/lib/contrast/agent/reporting/settings/sensitive_data_masking.rb +9 -1
  90. data/lib/contrast/agent/reporting/settings/sensitive_data_masking_rule.rb +7 -0
  91. data/lib/contrast/agent/reporting/settings/server_features.rb +8 -0
  92. data/lib/contrast/agent/reporting/settings/syslog.rb +176 -0
  93. data/lib/contrast/agent/reporting/settings/url_exclusion.rb +42 -0
  94. data/lib/contrast/agent/reporting/settings/validator.rb +17 -0
  95. data/lib/contrast/agent/request.rb +5 -7
  96. data/lib/contrast/agent/request_context.rb +8 -13
  97. data/lib/contrast/agent/request_context_extend.rb +8 -9
  98. data/lib/contrast/agent/request_handler.rb +10 -35
  99. data/lib/contrast/agent/rule_set.rb +4 -0
  100. data/lib/contrast/agent/service_heartbeat.rb +1 -1
  101. data/lib/contrast/agent/static_analysis.rb +6 -15
  102. data/lib/contrast/agent/telemetry/base.rb +35 -35
  103. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_base.rb +2 -0
  104. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_event.rb +2 -0
  105. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_message.rb +5 -2
  106. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_message_exception.rb +3 -0
  107. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_stack_frame.rb +3 -0
  108. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exceptions.rb +0 -1
  109. data/lib/contrast/agent/thread_watcher.rb +2 -6
  110. data/lib/contrast/agent/version.rb +1 -1
  111. data/lib/contrast/agent.rb +1 -3
  112. data/lib/contrast/api/communication/socket.rb +1 -0
  113. data/lib/contrast/api/decorators/message.rb +0 -6
  114. data/lib/contrast/api/decorators.rb +0 -3
  115. data/lib/contrast/components/assess.rb +0 -6
  116. data/lib/contrast/components/config.rb +18 -2
  117. data/lib/contrast/config/base_configuration.rb +0 -13
  118. data/lib/contrast/config/root_configuration.rb +1 -0
  119. data/lib/contrast/config/ruby_configuration.rb +2 -9
  120. data/lib/contrast/configuration.rb +0 -2
  121. data/lib/contrast/extension/assess/eval_trigger.rb +0 -4
  122. data/lib/contrast/extension/assess/hash.rb +3 -2
  123. data/lib/contrast/extension/assess/kernel.rb +22 -0
  124. data/lib/contrast/extension/assess/marshal.rb +16 -0
  125. data/lib/contrast/extension/assess/string.rb +21 -20
  126. data/lib/contrast/framework/base_support.rb +13 -4
  127. data/lib/contrast/framework/grape/support.rb +6 -6
  128. data/lib/contrast/framework/manager.rb +7 -23
  129. data/lib/contrast/framework/manager_extend.rb +1 -1
  130. data/lib/contrast/framework/rails/patch/action_controller_live_buffer.rb +11 -15
  131. data/lib/contrast/framework/rails/support.rb +9 -2
  132. data/lib/contrast/framework/sinatra/support.rb +3 -2
  133. data/lib/contrast/logger/aliased_logging.rb +33 -26
  134. data/lib/contrast/utils/assess/source_method_utils.rb +0 -9
  135. data/lib/contrast/utils/lru_cache.rb +3 -0
  136. data/lib/contrast/utils/middleware_utils.rb +2 -0
  137. data/lib/contrast/utils/response_utils.rb +14 -1
  138. data/lib/contrast/utils/telemetry.rb +9 -0
  139. data/lib/contrast/utils/telemetry_client.rb +7 -7
  140. data/lib/contrast/utils/telemetry_hash.rb +36 -12
  141. data/lib/contrast/utils/telemetry_identifier.rb +8 -0
  142. data/lib/contrast/utils/thread_tracker.rb +26 -9
  143. data/lib/contrast/utils/timer.rb +6 -1
  144. data/lib/contrast.rb +1 -3
  145. data/resources/assess/policy.json +2 -11
  146. data/ruby-agent.gemspec +1 -1
  147. metadata +36 -22
  148. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exceptions_report.rb +0 -30
  149. data/lib/contrast/api/decorators/application_update.rb +0 -52
  150. data/lib/contrast/api/decorators/library.rb +0 -56
  151. data/lib/contrast/api/decorators/library_usage_update.rb +0 -31
  152. data/lib/contrast/framework/platform_version.rb +0 -22
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ module Contrast
5
+ module Agent
6
+ module Reporting
7
+ module Settings
8
+ # The sanitizers defined by the user for use by the agent on this server for this organization.
9
+ class Sanitizer
10
+ ATTRIBUTES = %i[uuid api tags rules].cs__freeze
11
+
12
+ # @return uuid [String]
13
+ attr_accessor :uuid
14
+ # @return api [String]
15
+ attr_accessor :api
16
+ # @return uuid [Array<String>]
17
+ attr_accessor :tags
18
+ # @return uuid [Array<String>]
19
+ attr_accessor :rules
20
+
21
+ def initialize
22
+ @tags = []
23
+ @rules = []
24
+ end
25
+
26
+ def to_controlled_hash
27
+ {
28
+ api: api,
29
+ rules: rules,
30
+ tags: tags,
31
+ uuid: uuid
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -66,7 +66,7 @@ module Contrast
66
66
  # @param settings_rules [Hash] Response settings under Settings/sensitive_data_masking_policy/rules
67
67
  # @return rules [Array<Contrast::Agent::Reporting::Settings::SensitiveDataMaskingRule>, nil
68
68
  def build_rules_form_settings settings_rules
69
- return unless settings_rules || settings_rules.empty?
69
+ return if settings_rules.nil? || settings_rules.empty?
70
70
 
71
71
  settings_rules.each do |rule|
72
72
  instance = Contrast::Agent::Reporting::Settings::SensitiveDataMaskingRule.new
@@ -77,6 +77,14 @@ module Contrast
77
77
  rules
78
78
  end
79
79
 
80
+ def to_controlled_hash
81
+ {
82
+ rules: rules.map(&:to_controlled_hash),
83
+ mask_attack_vector: mask_attack_vector?,
84
+ mask_http_body: mask_http_body?
85
+ }
86
+ end
87
+
80
88
  private
81
89
 
82
90
  # Determine if parameter is array of Rules.
@@ -40,6 +40,13 @@ module Contrast
40
40
  @_keywords = words_array if string_array?(words_array)
41
41
  end
42
42
 
43
+ def to_controlled_hash
44
+ {
45
+ id: rule_id,
46
+ keywords: keywords
47
+ }
48
+ end
49
+
43
50
  private
44
51
 
45
52
  # Determine if a array is array of strings.
@@ -71,6 +71,14 @@ module Contrast
71
71
  def protect
72
72
  @_protect ||= Contrast::Agent::Reporting::Settings::ProtectServerFeature.new
73
73
  end
74
+
75
+ def to_controlled_hash
76
+ {
77
+ assessment: @_assess ? assess.to_controlled_hash : {},
78
+ defend: @_protect ? protect.to_controlled_hash : {},
79
+ telemetry: telemetry
80
+ }.compact
81
+ end
74
82
  end
75
83
  end
76
84
  end
@@ -0,0 +1,176 @@
1
+ # Copyright (c) 2022 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
+
6
+ module Contrast
7
+ module Agent
8
+ module Reporting
9
+ module Settings
10
+ # Controls for the syslogging feature in the agent
11
+ class Syslog
12
+ CONNECTION_TYPE = %w[UNENCRYPTED ENCRYPTED].cs__freeze
13
+ # Used for:
14
+ # severity_blocked, severity_blocked_perimeter, severity_exploited, severity_probed,
15
+ # severity_probed_perimeter
16
+ SEVERITIES = %w[ALERT CRITICAL ERROR WARNING NOTICE INFO DEBUG].cs__freeze
17
+ SYSLOG_METHODS = %i[
18
+ enable= ip= port= facility= protocol= connection_type= severity_exploited= severity_blocked=
19
+ severity_probed= severity_probed_suspicious= severity_blocked_perimeter= severity_probed_perimeter=
20
+ ].cs__freeze
21
+ SYSLOG_RESPONSE_KEYS = %i[
22
+ syslogEnabled syslogIpAddress syslogPortNumber syslogFacilityCode syslogProtocol
23
+ syslogConnectionType syslogSeverityExploited syslogSeverityBlocked syslogSeverityProbed
24
+ syslogSeveritySuspicious syslogSeverityBlockedPerimeter syslogSeverityProbedPerimeter
25
+ ].cs__freeze
26
+
27
+ # @return enable [Boolean]
28
+ attr_accessor :enable
29
+ # @return ip [Integer]
30
+ attr_accessor :ip
31
+ # @return port [Integer]
32
+ attr_accessor :port
33
+ # @return facility [Integer]
34
+ attr_accessor :facility
35
+ # @return protocol [String]
36
+ attr_accessor :protocol
37
+
38
+ def initialize
39
+ @enable = false
40
+ @ip = Contrast::Utils::ObjectShare::EMPTY_STRING
41
+ @port = 0
42
+ @facility = 0
43
+ end
44
+
45
+ # @return connection_type [String] one of UNENCRYPTED, ENCRYPTED
46
+ def connection_type
47
+ @_connection_type ||= Contrast::Utils::ObjectShare::EMPTY_STRING
48
+ end
49
+
50
+ # Set the connection type
51
+ #
52
+ # @param type [String, Symbol] one of UNENCRYPTED, ENCRYPTED
53
+ # @return connection_type [String] one of UNENCRYPTED, ENCRYPTED
54
+ def connection_type= type
55
+ @_connection_type = type if valid_entry?(type, CONNECTION_TYPE)
56
+ end
57
+
58
+ # @return severity_blocked [String]
59
+ def severity_blocked
60
+ @_severity_blocked ||= Contrast::Utils::ObjectShare::EMPTY_STRING
61
+ end
62
+
63
+ # Set the severity type
64
+ #
65
+ # @param severity [String, Symbol] one of UNENCRYPTED, ENCRYPTED
66
+ # @return connection_type [String] one of UNENCRYPTED, ENCRYPTED
67
+ def severity_blocked= severity
68
+ @_severity_blocked = severity if valid_entry?(severity, SEVERITIES)
69
+ end
70
+
71
+ # @return severity_blocked [String]
72
+ def severity_blocked_perimeter
73
+ @_severity_blocked_perimeter ||= Contrast::Utils::ObjectShare::EMPTY_STRING
74
+ end
75
+
76
+ # Set the severity type
77
+ #
78
+ # @param severity [String, Symbol] one of UNENCRYPTED, ENCRYPTED
79
+ # @return connection_type [String] one of UNENCRYPTED, ENCRYPTED
80
+ def severity_blocked_perimeter= severity
81
+ @_severity_blocked_perimeter = severity if valid_entry?(severity, SEVERITIES)
82
+ end
83
+
84
+ # @return severity_blocked [String]
85
+ def severity_exploited
86
+ @_severity_exploited ||= Contrast::Utils::ObjectShare::EMPTY_STRING
87
+ end
88
+
89
+ # Set the severity type
90
+ #
91
+ # @param severity [String, Symbol] one of UNENCRYPTED, ENCRYPTED
92
+ # @return connection_type [String] one of UNENCRYPTED, ENCRYPTED
93
+ def severity_exploited= severity
94
+ @_severity_exploited = severity if valid_entry?(severity, SEVERITIES)
95
+ end
96
+
97
+ # @return severity_blocked [String]
98
+ def severity_probed
99
+ @_severity_probed ||= Contrast::Utils::ObjectShare::EMPTY_STRING
100
+ end
101
+
102
+ # Set the severity type
103
+ #
104
+ # @param severity [String, Symbol] one of UNENCRYPTED, ENCRYPTED
105
+ # @return connection_type [String] one of UNENCRYPTED, ENCRYPTED
106
+ def severity_probed= severity
107
+ @_severity_probed = severity if valid_entry?(severity, SEVERITIES)
108
+ end
109
+
110
+ # @return severity_blocked [String]
111
+ def severity_probed_perimeter
112
+ @_severity_probed_perimeter ||= Contrast::Utils::ObjectShare::EMPTY_STRING
113
+ end
114
+
115
+ # Set the severity type
116
+ #
117
+ # @param severity [String, Symbol] one of UNENCRYPTED, ENCRYPTED
118
+ # @return connection_type [String] one of UNENCRYPTED, ENCRYPTED
119
+ def severity_probed_perimeter= severity
120
+ @_severity_probed_perimeter = severity if valid_entry?(severity, SEVERITIES)
121
+ end
122
+
123
+ # @return severity_blocked [String]
124
+ def severity_probed_suspicious
125
+ @_severity_probed_suspicious ||= Contrast::Utils::ObjectShare::EMPTY_STRING
126
+ end
127
+
128
+ # Set the severity type
129
+ #
130
+ # @param severity [String, Symbol] one of UNENCRYPTED, ENCRYPTED
131
+ # @return connection_type [String] one of UNENCRYPTED, ENCRYPTED
132
+ def severity_probed_suspicious= severity
133
+ @_severity_probed_suspicious = severity if valid_entry?(severity, SEVERITIES)
134
+ end
135
+
136
+ # @param settings_array [Array] Settings retrieved from response
137
+ def assign_array settings_array
138
+ Contrast::Agent::Reporting::Settings::Syslog::SYSLOG_METHODS.each_with_index do |method, index|
139
+ send(method, settings_array[SYSLOG_RESPONSE_KEYS[index]])
140
+ end
141
+ end
142
+
143
+ def to_controlled_hash
144
+ {
145
+ syslogEnabled: enable,
146
+ syslogIpAddress: ip,
147
+ syslogPortNumber: port,
148
+ syslogFacilityCode: facility,
149
+ syslogConnectionType: connection_type,
150
+ syslogProtocol: protocol,
151
+ syslogSeverityExploited: severity_exploited,
152
+ syslogSeverityBlocked: severity_blocked,
153
+ syslogSeverityProbed: severity_probed,
154
+ syslogSeveritySuspicious: severity_probed_suspicious,
155
+ syslogSeverityBlockedPerimeter: severity_blocked_perimeter,
156
+ syslogSeverityProbedPerimeter: severity_probed_perimeter
157
+ }
158
+ end
159
+
160
+ private
161
+
162
+ # Gets String or Symbol value and assigns it to iv after
163
+ # validation with allowed types.
164
+ #
165
+ # @param value [String, Symbol] value to write
166
+ # @param validation_hash [Hash] to validate against
167
+ def valid_entry? value, validation_hash
168
+ return false unless value && validation_hash
169
+
170
+ validation_hash.include?(value)
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,42 @@
1
+ # Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ require 'contrast/agent/reporting/settings/exclusion_base'
5
+ require 'contrast/utils/object_share'
6
+
7
+ module Contrast
8
+ module Agent
9
+ module Reporting
10
+ module Settings
11
+ # UrlExclusions class
12
+ class UrlExclusion < ExclusionBase
13
+ ATTRIBUTES = BASE_ATTRIBUTES.dup << :urls
14
+ ATTRIBUTES << :match_strategy
15
+ ATTRIBUTES.cs__freeze
16
+ STRATEGIES = %w[ALL ONLY].cs__freeze
17
+
18
+ # @return urls [Array<String>]
19
+ attr_accessor :urls
20
+
21
+ # @return match_strategy [String] The type of the input
22
+ def match_strategy
23
+ @_match_strategy ||= Contrast::Utils::ObjectShare::EMPTY_STRING
24
+ end
25
+
26
+ # @param new_strategy [String] Set new input type.
27
+ # @return type [String] The type of the input.
28
+ def match_strategy= new_strategy
29
+ @_match_strategy = new_strategy if STRATEGIES.include?(new_strategy)
30
+ end
31
+
32
+ def to_controlled_hash
33
+ hash = super
34
+ hash[:urls] = urls
35
+ hash[:matchStrategy] = match_strategy
36
+ hash
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,17 @@
1
+ # Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ require 'contrast/agent/reporting/settings/sanitizer'
5
+
6
+ module Contrast
7
+ module Agent
8
+ module Reporting
9
+ module Settings
10
+ # The validators defined by the user for use by the agent on this server for this organization.
11
+ class Validator < Sanitizer
12
+ # This uses the same fields as Sanitizer.
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -17,12 +17,6 @@ module Contrast
17
17
  # provides access to the original Rack::Request object as well as extracts
18
18
  # data in a format that the Agent expects, caching those transformations in
19
19
  # order to avoid repeatedly creating Strings & thrashing GC.
20
- #
21
- # @attr_reader rack_request [Rack::Request] The passed to the Agent RackRequest to be wrapped.
22
- # @attr_accessor route [Contrast::Api::Dtm::RouteCoverage] the route, used for findings, of this request
23
- # @attr_accessor observed_route [Contrast::Api::Dtm::ObservedRoute] the route, used for coverage of this request
24
- # @attr_accessor new_observed_route [Contrast::Agent::Reporting::ObservedRoute] the route, used for coverage, of
25
- # this request
26
20
  class Request
27
21
  include Contrast::Utils::RequestUtils
28
22
  include Contrast::Components::Logger::InstanceMethods
@@ -37,8 +31,12 @@ module Contrast
37
31
  STATIC_SUFFIXES = /\.(?:js|css|jpeg|jpg|gif|png|ico|woff|svg|pdf|eot|ttf|jar)$/i.cs__freeze
38
32
  MEDIA_TYPE_MARKERS = %w[image/ text/css text/javascript].cs__freeze
39
33
 
34
+ # @return [Rack::Request] The passed to the Agent RackRequest to be wrapped.
40
35
  attr_reader :rack_request
41
- attr_accessor :route, :observed_route, :new_observed_route
36
+ # @return [Contrast::Api::Dtm::RouteCoverage] the route, used for findings, of this request
37
+ attr_accessor :route
38
+ # @return [Contrast::Agent::Reporting::ObservedRoute] the route, used for coverage, of this request
39
+ attr_accessor :observed_route
42
40
 
43
41
  # Delegate calls to the following methods to the attribute @rack_request
44
42
  def_delegators :@rack_request, :base_url, :cookies, :env, :ip, :media_type, :path, :port, :query_string,
@@ -30,8 +30,6 @@ module Contrast
30
30
  # @return [Hash] context used to log the request
31
31
  attr_reader :logging_hash
32
32
  # @return [Contrast::Agent::Reporting::ObservedRoute] the route, used for coverage, of this request
33
- attr_reader :new_observed_route
34
- # @return [Contrast::Api::Dtm::ObservedRoute] the route, used for coverage, of this request
35
33
  attr_reader :observed_route
36
34
  # @return [Contrast::Agent::Request] our wrapper around the Rack::Request for this context
37
35
  attr_reader :request
@@ -40,8 +38,6 @@ module Contrast
40
38
  attr_reader :response
41
39
  # @return [Contrast::Api::Dtm::RouteCoverage] the route, used for findings, of this request
42
40
  attr_reader :route
43
- # @return [Contrast::Api::Dtm::ServerActivity] the server activity found in this request
44
- attr_reader :server_activity
45
41
  # @return [Contrast::Api::Settings::InputAnalysis] the protect input analysis of sources on this request
46
42
  attr_reader :speedracer_input_analysis
47
43
  # @return [Contrast::Utils::Timer] when the context was created
@@ -59,8 +55,6 @@ module Contrast
59
55
  @activity = Contrast::Api::Dtm::Activity.new
60
56
  @activity.http_request = request.dtm
61
57
 
62
- @server_activity = Contrast::Api::Dtm::ServerActivity.new
63
-
64
58
  # build analyzer
65
59
  @do_not_track = false
66
60
  @speedracer_input_analysis = EMPTY_INPUT_ANALYSIS_PB
@@ -124,20 +118,21 @@ module Contrast
124
118
 
125
119
  def reset_activity
126
120
  @activity = Contrast::Api::Dtm::Activity.new(http_request: request.dtm)
127
- @server_activity = Contrast::Api::Dtm::ServerActivity.new
128
- @observed_route = Contrast::Api::Dtm::ObservedRoute.new # TODO: RUBY-1438 -- remove
129
- @new_observed_route = Contrast::Agent::Reporting::ObservedRoute.new
121
+ @observed_route = Contrast::Agent::Reporting::ObservedRoute.new
130
122
  end
131
123
 
132
124
  private
133
125
 
134
126
  def handle_routes
135
- @observed_route = Contrast::Api::Dtm::ObservedRoute.new # TODO: RUBY-1438 -- remove
136
- @new_observed_route = Contrast::Agent::Reporting::ObservedRoute.new
127
+ @observed_route = Contrast::Agent::Reporting::ObservedRoute.new
128
+ # TODO: RUBY-1705 when we no longer need the DTM style, delete this method and use the get_route_information
129
+ # instead.
137
130
  route_dtm = Contrast::Agent.framework_manager.get_route_dtm(@request)
138
- new_route_coverage_dtm = Contrast::Agent.framework_manager.get_route_information(@request)
131
+ # new_route_coverage_dtm = Contrast::Agent.framework_manager.get_route_information(@request)
132
+ # TODO: RUBY-1705 -- delete append_route_coverage
139
133
  append_route_coverage(route_dtm)
140
- append_to_new_observed_route(new_route_coverage_dtm)
134
+ # TODO: RUBY-1705 -- change to take [Contrast::Agent::Reporting::ObservedRoute]
135
+ append_to_observed_route(route_dtm)
141
136
  end
142
137
  end
143
138
  end
@@ -38,23 +38,20 @@ module Contrast
38
38
  @activity.routes << route
39
39
 
40
40
  # For TS routes
41
- @observed_route.signature = route.route
42
- @observed_route.verb = route.verb
43
- @observed_route.url = route.url if route.url
44
41
  @request.route = route
45
- @request.observed_route = @observed_route
46
42
  end
47
43
 
48
44
  # Convert the discovered route for this request to appropriate forms and disseminate it to those locations
49
45
  # where it is necessary for our route coverage and finding vulnerability discovery features to function.
50
46
  #
51
- def append_to_new_observed_route route
47
+ # @param route [Contrast::Api::Dtm::RouteCoverage]
48
+ def append_to_observed_route route
52
49
  return unless route
53
50
 
54
- @new_observed_route.signature = route.route
55
- @new_observed_route.verb = route.verb
56
- @new_observed_route.url = route.url if route.url
57
- @request.new_observed_route = @new_observed_route
51
+ @observed_route.signature = route.route
52
+ @observed_route.verb = route.verb
53
+ @observed_route.url = route.url if route.url
54
+ @request.observed_route = @observed_route
58
55
  end
59
56
 
60
57
  # Collect the results for the given rule with the given action
@@ -71,6 +68,7 @@ module Contrast
71
68
  end
72
69
  end
73
70
 
71
+ # @raise [Contrast::SecurityException]
74
72
  def service_extract_request
75
73
  return false unless ::Contrast::AGENT.enabled?
76
74
  return false unless ::Contrast::PROTECT.enabled?
@@ -105,6 +103,7 @@ module Contrast
105
103
  # Normally these should be generated on Speedracer for any attacks detected during prefilter.
106
104
  #
107
105
  # @param agent_settings [Contrast::Api::Settings::AgentSettings]
106
+ # @raise[Contrast::SecurityException]
108
107
  def handle_protect_state agent_settings
109
108
  return unless agent_settings&.protect_state
110
109
 
@@ -22,52 +22,27 @@ module Contrast
22
22
  @ruleset = ::Contrast::AGENT.ruleset
23
23
  end
24
24
 
25
- # Send Activities messages to TS [Contrast::Agent::Reporting::ServerActivity,
26
- # Contrast::Api::Dtm::ServerActivity,
27
- # Contrast::Api::Dtm::Activity,
28
- # Contrast::Api::Dtm::ObservedRoute]
29
- # If bypass is enabled use the reporting service if not than the messages are
30
- # send with speedracer
31
- # TODO: RUBY-1355
32
- # TODO: RUBY-1358
33
- # TODO: RUBY-1438 -- remove
25
+ # Send Activities messages to TS [Contrast::Api::Dtm::Activity]
26
+ # TODO: RUBY-1704
27
+ # TODO: RUBY-1438
34
28
  def send_activity_messages
35
- events = [context.activity]
36
- unless Contrast::Agent::Reporter.enabled?
37
- Contrast::Agent::Inventory::DependencyUsageAnalysis.instance.generate_library_usage(context.activity)
38
- events << context.server_activity
39
- events << context.observed_route
40
- end
41
- events.each do |message|
42
- Contrast::Agent.messaging_queue&.send_event_eventually(message)
43
- end
29
+ Contrast::Agent.messaging_queue&.send_event_eventually(context.activity)
44
30
  end
45
31
 
46
32
  # reports events[Contrast::Agent::Reporting::ReporterEvent] to TS
47
33
  # This method is used to send our JSON messages directly to TeamServer at the end of each request. As we move
48
34
  # more endpoints over, this method will take the messages originally sent by #send_actiivty_messages. At the end,
49
35
  # that method should be removed.
50
- def report_activity # rubocop:disable Metrics/AbcSize
51
- return unless Contrast::Agent::Reporter.enabled?
36
+ def report_activity
37
+ return unless (reporter = Contrast::Agent.reporter)
52
38
 
53
- reporter = Contrast::Agent.reporter
54
- return unless reporter
39
+ reporter.send_event(context.observed_route)
40
+ return unless Contrast::Agent::Reporter.enabled?
55
41
 
56
42
  # Mask Sensitive Data
57
43
  Contrast::Agent::Reporting::Masker.mask(context.activity)
58
-
59
- Contrast::Agent::Inventory::DependencyUsageAnalysis.instance.generate_library_usage(context.activity)
60
- [
61
- context.new_observed_route,
62
- Contrast::Agent::Reporting::DtmMessage.dtm_to_event(context.server_activity),
63
- Contrast::Agent::Reporting::DtmMessage.dtm_to_event(context.activity.library_usages),
64
- Contrast::Agent::Reporting::DtmMessage.dtm_to_event(context.activity)
65
- ].each do |event|
66
- reporter.send_event(event)
67
- rescue StandardError => e
68
- logger.warn('Unable to send Event Activity', e)
69
- end
70
- context.activity.library_usages.clear # TODO: RUBY-1355 remove when no longer using activity
44
+ event = Contrast::Agent::Reporting::DtmMessage.dtm_to_event(context.activity)
45
+ reporter.send_event(event)
71
46
  end
72
47
 
73
48
  # If the response is streaming, we should only perform filtering on our stream safe rules
@@ -14,6 +14,8 @@ module Contrast
14
14
  # The main action here is snapshotting the request as provided to the application from the
15
15
  # user before any application code has acted upon it. Additionally, this is where Protect will
16
16
  # terminate requests on attack detection if set to block at perimeter
17
+ #
18
+ # @raise [Contrast::SecurityException] raises error if security exception is thrown in prefilter
17
19
  def prefilter
18
20
  context = Contrast::Agent::REQUEST_TRACKER.current
19
21
  return unless context&.analyze_request?
@@ -30,6 +32,8 @@ module Contrast
30
32
 
31
33
  # The filtering that needs occur after the application has acted on the request and the response
32
34
  # has been created. The main actions here are analyzing the response for unsafe state or actions.
35
+ #
36
+ # @raise [Contrast::SecurityException] raises error if security exception is thrown in postfilter
33
37
  def postfilter
34
38
  context = Contrast::Agent::REQUEST_TRACKER.current
35
39
  return unless context&.analyze_response?
@@ -22,7 +22,7 @@ module Contrast
22
22
  @_thread = Contrast::Agent::Thread.new do
23
23
  logger.info('Starting heartbeat thread.')
24
24
  loop do
25
- Contrast::Agent.messaging_queue.send_event_eventually(poll_message)
25
+ Contrast::Agent.messaging_queue&.send_event_eventually(poll_message)
26
26
  sleep(REFRESH_INTERVAL_SEC)
27
27
  end
28
28
  end
@@ -4,7 +4,6 @@
4
4
  require 'contrast/components/logger'
5
5
  require 'contrast/components/scope'
6
6
  require 'contrast/agent/reporting/reporting_events/application_update'
7
- require 'contrast/api/decorators/application_update'
8
7
 
9
8
  module Contrast
10
9
  module Agent
@@ -24,23 +23,15 @@ module Contrast
24
23
  end
25
24
  end
26
25
 
27
- # TODO: RUBY-1356
28
26
  def send_inventory_message
29
27
  return unless ::Contrast::INVENTORY.enabled?
30
28
 
31
- app_update_msg = Contrast::Api::Dtm::ApplicationUpdate.build
32
-
33
- Contrast::Agent::Inventory::DatabaseConfig.append_db_config(app_update_msg)
34
- # TODO: RUBY-1438 -- remove and build ReportingEvent directly
35
- if Contrast::Agent.reporter
36
- report = Contrast::Agent::Reporting::DtmMessage.dtm_to_event(app_update_msg)
37
- Contrast::Agent.reporter.send_event(report)
38
-
39
- # This is being reported separately because we extract the data from the same message
40
- inventory_report = Contrast::Agent::Reporting::ApplicationInventory.convert(app_update_msg)
41
- Contrast::Agent.reporter.send_event(inventory_report)
42
- else
43
- Contrast::Agent.messaging_queue.send_event_eventually(app_update_msg, force: true)
29
+ report = Contrast::Agent::Reporting::ApplicationUpdate.new
30
+ # This convert here is left as it'll be easier to be replaced when the Library is being changed
31
+ report.libraries = Contrast::Agent::Inventory::DependencyAnalysis.instance.library_pb_list
32
+ Contrast::Agent::Inventory::DatabaseConfig.append_db_config(report)
33
+ [report, Contrast::Agent::Reporting::ApplicationInventory.new].each do |e|
34
+ Contrast::Agent.reporter.send_event(e)
44
35
  end
45
36
  end
46
37