contrast-agent 5.1.0 → 5.2.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.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/ext/cs__assess_kernel/cs__assess_kernel.c +7 -4
  3. data/ext/cs__assess_module/cs__assess_module.c +7 -7
  4. data/ext/cs__common/cs__common.c +4 -0
  5. data/ext/cs__common/cs__common.h +1 -0
  6. data/ext/cs__contrast_patch/cs__contrast_patch.c +52 -27
  7. data/ext/cs__contrast_patch/cs__contrast_patch.h +2 -0
  8. data/ext/cs__scope/cs__scope.c +747 -0
  9. data/ext/cs__scope/cs__scope.h +88 -0
  10. data/ext/cs__scope/extconf.rb +5 -0
  11. data/lib/contrast/agent/assess/contrast_event.rb +20 -13
  12. data/lib/contrast/agent/assess/contrast_object.rb +4 -1
  13. data/lib/contrast/agent/assess/policy/propagation_node.rb +2 -5
  14. data/lib/contrast/agent/assess/policy/propagator/match_data.rb +2 -0
  15. data/lib/contrast/agent/assess/policy/trigger_method.rb +4 -1
  16. data/lib/contrast/agent/assess/rule/response/{autocomplete_rule.rb → auto_complete_rule.rb} +4 -3
  17. data/lib/contrast/agent/assess/rule/response/base_rule.rb +12 -79
  18. data/lib/contrast/agent/assess/rule/response/body_rule.rb +109 -0
  19. data/lib/contrast/agent/assess/rule/response/cache_control_header_rule.rb +157 -0
  20. data/lib/contrast/agent/assess/rule/response/click_jacking_header_rule.rb +26 -0
  21. data/lib/contrast/agent/assess/rule/response/csp_header_insecure_rule.rb +14 -15
  22. data/lib/contrast/agent/assess/rule/response/csp_header_missing_rule.rb +5 -25
  23. data/lib/contrast/agent/assess/rule/response/framework/rails_support.rb +29 -0
  24. data/lib/contrast/agent/assess/rule/response/header_rule.rb +70 -0
  25. data/lib/contrast/agent/assess/rule/response/hsts_header_rule.rb +12 -36
  26. data/lib/contrast/agent/assess/rule/response/parameters_pollution_rule.rb +2 -1
  27. data/lib/contrast/agent/assess/rule/response/x_content_type_header_rule.rb +26 -0
  28. data/lib/contrast/agent/assess/rule/response/x_xss_protection_header_rule.rb +36 -0
  29. data/lib/contrast/agent/middleware.rb +1 -0
  30. data/lib/contrast/agent/patching/policy/after_load_patcher.rb +1 -3
  31. data/lib/contrast/agent/patching/policy/patch.rb +2 -6
  32. data/lib/contrast/agent/patching/policy/patcher.rb +1 -1
  33. data/lib/contrast/agent/protect/input_analyzer/input_analyzer.rb +94 -0
  34. data/lib/contrast/agent/protect/rule/base.rb +28 -1
  35. data/lib/contrast/agent/protect/rule/base_service.rb +10 -1
  36. data/lib/contrast/agent/protect/rule/cmd_injection.rb +2 -0
  37. data/lib/contrast/agent/protect/rule/deserialization.rb +6 -0
  38. data/lib/contrast/agent/protect/rule/http_method_tampering.rb +5 -1
  39. data/lib/contrast/agent/protect/rule/no_sqli.rb +1 -0
  40. data/lib/contrast/agent/protect/rule/path_traversal.rb +1 -0
  41. data/lib/contrast/agent/protect/rule/sqli/sqli_input_classification.rb +124 -0
  42. data/lib/contrast/agent/protect/rule/sqli/sqli_worth_watching.rb +121 -0
  43. data/lib/contrast/agent/protect/rule/sqli.rb +33 -0
  44. data/lib/contrast/agent/protect/rule/xxe.rb +4 -0
  45. data/lib/contrast/agent/reporting/input_analysis/input_analysis.rb +44 -0
  46. data/lib/contrast/agent/reporting/input_analysis/input_analysis_result.rb +115 -0
  47. data/lib/contrast/agent/reporting/input_analysis/input_type.rb +44 -0
  48. data/lib/contrast/agent/reporting/input_analysis/score_level.rb +21 -0
  49. data/lib/contrast/agent/reporting/report.rb +1 -0
  50. data/lib/contrast/agent/reporting/reporter.rb +8 -1
  51. data/lib/contrast/agent/reporting/reporting_events/finding.rb +69 -36
  52. data/lib/contrast/agent/reporting/reporting_events/finding_event.rb +88 -59
  53. data/lib/contrast/agent/reporting/reporting_events/{finding_object.rb → finding_event_object.rb} +24 -20
  54. data/lib/contrast/agent/reporting/reporting_events/finding_event_parent_object.rb +39 -0
  55. data/lib/contrast/agent/reporting/reporting_events/finding_event_property.rb +40 -0
  56. data/lib/contrast/agent/reporting/reporting_events/{finding_signature.rb → finding_event_signature.rb} +29 -24
  57. data/lib/contrast/agent/reporting/reporting_events/finding_event_source.rb +12 -8
  58. data/lib/contrast/agent/reporting/reporting_events/{finding_stack.rb → finding_event_stack.rb} +23 -19
  59. data/lib/contrast/agent/reporting/reporting_events/{finding_taint_range.rb → finding_event_taint_range.rb} +17 -15
  60. data/lib/contrast/agent/reporting/reporting_events/finding_request.rb +26 -53
  61. data/lib/contrast/agent/reporting/reporting_events/poll.rb +29 -0
  62. data/lib/contrast/agent/reporting/reporting_events/reporting_event.rb +5 -4
  63. data/lib/contrast/agent/reporting/reporting_events/route_discovery.rb +1 -0
  64. data/lib/contrast/agent/reporting/reporting_events/server_activity.rb +1 -1
  65. data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +10 -3
  66. data/lib/contrast/agent/reporting/reporting_utilities/endpoints.rb +0 -1
  67. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +1 -0
  68. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +28 -20
  69. data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +1 -1
  70. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +13 -1
  71. data/lib/contrast/agent/request_context.rb +6 -1
  72. data/lib/contrast/agent/request_context_extend.rb +85 -21
  73. data/lib/contrast/agent/scope.rb +102 -107
  74. data/lib/contrast/agent/service_heartbeat.rb +45 -2
  75. data/lib/contrast/agent/version.rb +1 -1
  76. data/lib/contrast/api/decorators/bot_blocker.rb +37 -0
  77. data/lib/contrast/api/decorators/ip_denylist.rb +37 -0
  78. data/lib/contrast/api/decorators/rasp_rule_sample.rb +29 -0
  79. data/lib/contrast/api/decorators/user_input.rb +11 -1
  80. data/lib/contrast/api/decorators/virtual_patch.rb +34 -0
  81. data/lib/contrast/components/logger.rb +5 -0
  82. data/lib/contrast/components/protect.rb +4 -2
  83. data/lib/contrast/components/scope.rb +98 -91
  84. data/lib/contrast/config/agent_configuration.rb +58 -12
  85. data/lib/contrast/config/api_configuration.rb +100 -12
  86. data/lib/contrast/config/api_proxy_configuration.rb +55 -3
  87. data/lib/contrast/config/application_configuration.rb +114 -15
  88. data/lib/contrast/config/assess_configuration.rb +106 -12
  89. data/lib/contrast/config/assess_rules_configuration.rb +44 -3
  90. data/lib/contrast/config/base_configuration.rb +1 -0
  91. data/lib/contrast/config/certification_configuration.rb +74 -3
  92. data/lib/contrast/config/exception_configuration.rb +61 -3
  93. data/lib/contrast/config/heap_dump_configuration.rb +101 -17
  94. data/lib/contrast/config/inventory_configuration.rb +64 -3
  95. data/lib/contrast/config/logger_configuration.rb +46 -3
  96. data/lib/contrast/config/protect_rule_configuration.rb +36 -9
  97. data/lib/contrast/config/protect_rules_configuration.rb +120 -17
  98. data/lib/contrast/config/request_audit_configuration.rb +68 -3
  99. data/lib/contrast/config/ruby_configuration.rb +96 -22
  100. data/lib/contrast/config/sampling_configuration.rb +76 -10
  101. data/lib/contrast/config/server_configuration.rb +56 -11
  102. data/lib/contrast/configuration.rb +6 -3
  103. data/lib/contrast/logger/cef_log.rb +151 -0
  104. data/lib/contrast/utils/hash_digest.rb +14 -6
  105. data/lib/contrast/utils/log_utils.rb +114 -0
  106. data/lib/contrast/utils/middleware_utils.rb +6 -7
  107. data/lib/contrast/utils/net_http_base.rb +12 -9
  108. data/lib/contrast/utils/patching/policy/patch_utils.rb +0 -4
  109. data/lib/contrast.rb +4 -3
  110. data/ruby-agent.gemspec +1 -1
  111. data/service_executables/VERSION +1 -1
  112. data/service_executables/linux/contrast-service +0 -0
  113. data/service_executables/mac/contrast-service +0 -0
  114. metadata +41 -21
  115. data/lib/contrast/agent/assess/rule/response/cachecontrol_rule.rb +0 -184
  116. data/lib/contrast/agent/assess/rule/response/clickjacking_rule.rb +0 -66
  117. data/lib/contrast/agent/assess/rule/response/x_content_type_rule.rb +0 -52
  118. data/lib/contrast/agent/assess/rule/response/x_xss_protection_rule.rb +0 -53
  119. data/lib/contrast/extension/kernel.rb +0 -54
@@ -0,0 +1,151 @@
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 'logger'
5
+ require 'singleton'
6
+
7
+ require 'contrast/extension/module'
8
+ require 'contrast/logger/application'
9
+ require 'contrast/logger/format'
10
+ require 'contrast/logger/request'
11
+ require 'contrast/logger/time'
12
+ require 'contrast/logger/log'
13
+ require 'contrast/components/config'
14
+ require 'contrast/utils/log_utils'
15
+
16
+ module Contrast
17
+ # Used as a wrapper around our logging. The module option specifically adds in a new method for error that raises the
18
+ # logged exception, used in testing so that we can see if anything unexpected happens without it being swallowed
19
+ # while still providing safe options for customers.
20
+ module Logger
21
+ # For development set following env var to raise logged exceptions instead of just logging.
22
+ if ENV['CONTRAST__AGENT__RUBY_MORE_COWBELL']
23
+ ::Logger.class_eval do
24
+ alias_method :cs__error, :error
25
+ alias_method :cs__warn, :warn
26
+
27
+ def error *args, **kwargs
28
+ if kwargs.empty?
29
+ cs__error(*args)
30
+ else
31
+ cs__error(*args, **kwargs)
32
+ end
33
+ args.each { |arg| raise arg if arg && arg.cs__class < Exception }
34
+ end
35
+ end
36
+ end
37
+
38
+ # This is the CEF Logger implementation. It uses the default ::Logger.
39
+ class CEFLog
40
+ include Singleton
41
+ include ::Contrast::Utils::LogUtils
42
+ include ::Contrast::Utils::CEFLogUtils
43
+
44
+ attr_reader :previous_path, :previous_level
45
+
46
+ def initialize
47
+ build_logger
48
+ end
49
+
50
+ # Given new settings from TeamServer, update our logging to use the new file and level, assuming they weren't
51
+ # set by local configuration.
52
+ #
53
+ # @param log_level [String] the level at which to log, as provided by TeamServer settings
54
+ def build_logger log_level = nil
55
+ current_level_const = find_valid_level(log_level)
56
+ level_change = current_level_const != previous_level
57
+
58
+ # don't needlessly recreate logger
59
+ return if @cef_logger && !level_change
60
+
61
+ @previous_level = current_level_const
62
+
63
+ @_cef_logger = build(path: DEFAULT_CEF_NAME, level_const: current_level_const)
64
+ # If we're logging to a new path, then let's start it w/ our helpful
65
+ # data gathering messages
66
+ # log_update if path_change
67
+ rescue StandardError => e
68
+ # rubocop:disable Rails/Output
69
+ if @_cef_logger
70
+ @_cef_logger.error('Unable to process update to LoggerManager.', e)
71
+ else
72
+ puts 'Unable to process update to LoggerManager.'
73
+ raise e if ENV['CONTRAST__AGENT__RUBY_MORE_COWBELL']
74
+
75
+ puts e.message
76
+ puts e.backtrace.join("\n")
77
+ end
78
+ # rubocop:enable Rails/Output
79
+ end
80
+
81
+ def cef_logger
82
+ @_cef_logger
83
+ end
84
+
85
+ def log msg, level = @_cef_logger.level
86
+ case level
87
+ when ::Logger::Severity::INFO
88
+ @_cef_logger.info(msg)
89
+ when ::Logger::Severity::ERROR
90
+ @_cef_logger.error(msg)
91
+ when ::Logger::Severity::WARN
92
+ @_cef_logger.warn(msg)
93
+ when ::Logger::Severity::FATAL
94
+ @_cef_logger.fatal(msg)
95
+ else
96
+ @_cef_logger.debug(msg)
97
+ end
98
+ end
99
+
100
+ def virtual_patch_message patch, outcome
101
+ message = "Virtual Patch #{ patch.fetch(:name, '') } - #{ patch[:uuid] } was triggered by this request."
102
+ log [message, patch, outcome], ::Logger::Severity::DEBUG
103
+ end
104
+
105
+ def bot_blocking_message matching_bot, outcome
106
+ message = "User agent #{ matching_bot[:user_agent] } matched the disallowed value #{ matching_bot[:bot] }"
107
+ log [message, matching_bot, outcome], ::Logger::Severity::DEBUG
108
+ end
109
+
110
+ def ip_denylisted_message remote_ip, block_entry, outcome
111
+ message = "IP Address #{ remote_ip } matched the disallowed value" \
112
+ "#{ block_entry[:ip] } in the IP Blacklist #{ block_entry[:uuid] }"
113
+ log [message, block_entry, outcome], ::Logger::Severity::DEBUG
114
+ end
115
+
116
+ def successful_attack rule_id, outcome, input_type = nil, input_value = nil
117
+ if input_type.present? && input_value.present?
118
+ successful_attack_with_input = "#{ input_type } had a value that successfully exploited" \
119
+ "#{ rule_id } - #{ input_value }"
120
+ log [successful_attack_with_input, rule_id, outcome], ::Logger::Severity::WARN
121
+ else
122
+ successful_attack_wo_input = "An effective attack was detected against #{ rule_id }"
123
+ log [successful_attack_wo_input, rule_id, outcome], ::Logger::Severity::WARN
124
+ end
125
+ end
126
+
127
+ def ineffective_attack rule_id, outcome, input_type = nil, input_value = nil
128
+ if input_type.present? && input_value.present?
129
+ ineffective_attack_with_input = "#{ input_type } had a value that matched a signature for, " \
130
+ "but did not successfully exploit #{ rule_id } - #{ input_value }"
131
+ log [ineffective_attack_with_input, rule_id, outcome], ::Logger::Severity::WARN
132
+ else
133
+ ineffective_attack_wo_input = "An unsuccessful attack was detected against #{ rule_id }"
134
+ log [ineffective_attack_wo_input, rule_id, outcome], ::Logger::Severity::WARN
135
+ end
136
+ end
137
+
138
+ # newer - currently not in the agent, currently is a probe for us
139
+ def suspicious_attack rule_id, outcome, input_type = nil, input_value = nil
140
+ if input_type.present? && input_value.present?
141
+ suspicious_attack_with = "#{ input_type } included a potential attack value that was detected" \
142
+ "as suspicious using #{ rule_id } - #{ input_value }"
143
+ log [suspicious_attack_with, rule_id, outcome], ::Logger::WARN
144
+ elsif input_value.present?
145
+ suspicious_attack_without = 'Suspicious activity indicates a potential attack using ' + rule_id.to_s
146
+ log [suspicious_attack_without, rule_id, outcome], ::Logger::WARN
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
@@ -29,7 +29,7 @@ module Contrast
29
29
  # request or Contrast::REQUEST_TRACKER.current.request uri and used request
30
30
  # method.
31
31
  #
32
- # @param finding [Contrast::Api::Dtm::Finding] finding to be reported
32
+ # @param finding [Contrast::Api::Dtm::Finding, Contrast::Agent::Reporting::Finding] finding to be reported
33
33
  # @param request [Contrast::Agent::Request] our wrapper around the Rack::Request.
34
34
  # @return checksum [Integer, nil] returns nil if there is no request context or tracking
35
35
  # is disabled.
@@ -38,12 +38,20 @@ module Contrast
38
38
  return unless context || ::Contrast::ASSESS.non_request_tracking?
39
39
 
40
40
  if (route = finding.routes[0])
41
- update(route.route) # the normalized URL used to access the method in the route.
42
- update(route.verb) # the HTTP Verb used to access the method in the route.
43
- elsif request ||= context&.request
44
- update(request.normalized_uri) # the normalized URL used to access the method in the route.
45
- update(request.request_method) # The HTTP method used in the request
41
+ if finding.cs__is_a?(Contrast::Agent::Reporting::Finding) && (observation = route.observations[0])
42
+ update(observation.url)
43
+ update(observation.verb)
44
+ else
45
+ update(route.route) # the normalized URL used to access the method in the route.
46
+ update(route.verb) # the HTTP Verb used to access the method in the route.
47
+ end
48
+ return
46
49
  end
50
+
51
+ return unless request ||= context&.request
52
+
53
+ update(request.normalized_uri) # the normalized URL used to access the method in the route.
54
+ update(request.request_method) # The HTTP method used in the request
47
55
  end
48
56
 
49
57
  # Update to CRC checksum the event source name and source type.
@@ -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 'socket'
5
+ require 'contrast/agent/version'
6
+
4
7
  module Contrast
5
8
  module Utils
6
9
  # Method utility used by Contrast::Logger::log
@@ -106,3 +109,114 @@ module Contrast
106
109
  end
107
110
  end
108
111
  end
112
+
113
+ module Contrast
114
+ module Utils
115
+ # These are the utilities for the CEF Logger, which will use the default ruby logger as we are not
116
+ # interested in special logging. We have the format we need and that's all we need. It would be useless
117
+ # to use Ougai
118
+ module CEFLogUtils
119
+ include Contrast::Utils::LogUtils
120
+ # <date> <host> CEF:<version>|<company>|<product>|<agent version>|<event type>
121
+ # |<event message>|<severity>|<other name-value pairs>
122
+ DEFAULT_CEF_NAME = 'security.log'
123
+ DEFAULT_LEVEL = ::Logger::Severity::INFO
124
+ VALID_LEVELS = ::Logger::SEV_LABEL
125
+ PROGNAME = 'Contrast Agent Ruby'
126
+ DATE_TIME_FORMAT = '%b %d %Y %H:%M:%S.%L%z'
127
+ AGENT_VERSION = Contrast::Agent::VERSION
128
+ EVENT_TYPE = 'SECURITY'
129
+ DEFAULT_METADATA = '-'
130
+
131
+ private
132
+
133
+ def build path: STDOUT_STR, level_const: DEFAULT_LEVEL
134
+ logger = case path
135
+ when STDOUT_STR, STDERR_STR
136
+ ::Logger.new(Object.cs__const_get(path))
137
+ else
138
+ ::Logger.new(path)
139
+ end
140
+ logger.progname = PROGNAME
141
+ logger.level = level_const
142
+ change_logger_formatter logger
143
+ logger
144
+ end
145
+
146
+ def context
147
+ Contrast::Agent::REQUEST_TRACKER.current
148
+ end
149
+
150
+ def change_logger_formatter logger
151
+ ip_address = extract_ip_address
152
+ logger.formatter = proc do |severity, datetime, progname, msg|
153
+ date_format = datetime.strftime(DATE_TIME_FORMAT)
154
+ message = []
155
+ message << "#{ date_format } #{ ip_address }"
156
+ message << 'CEF:0|Contrast Security'
157
+ message << progname
158
+ message << AGENT_VERSION
159
+ message << EVENT_TYPE
160
+ message << msg[0]
161
+ message << severity
162
+ message << extract_metadata(msg[1], msg[2])
163
+ message.join('|') + "\n"
164
+ end
165
+ end
166
+
167
+ # This method will extract the metadata information from context and other places
168
+ #
169
+ # initial structure of the data:
170
+ # <metadata> := <message-source>" "<source-ip>" "<source-port>" "<request-url>" "<request-method>" \
171
+ # "<application>" "<outcome>
172
+ # it could come from: blockEntry, lei, bbi(bot blocker), vp(virtual patch) or pri(rule)
173
+ # initially here we will use case to add it
174
+ def extract_metadata rule_id = nil, outcome = nil
175
+ message = []
176
+ sender_info = context&.activity&.http_request&.sender
177
+ rule_id ? message << "pri=#{ rule_id } " : 'asd'
178
+ request_method = if context.request.rack_request.env['REQUEST_METHOD'].length.positive?
179
+ context.request.rack_request.env['REQUEST_METHOD']
180
+ else
181
+ DEFAULT_METADATA
182
+ end
183
+ app_name = ::Contrast::APP_CONTEXT.app_name
184
+ attach_request_and_sender_info message, sender_info
185
+ message << "request=#{ context.request.url } "
186
+ message << "requestMethod=#{ request_method } "
187
+ message << "app=#{ app_name } "
188
+ message << "outcome=#{ outcome } "
189
+ end
190
+
191
+ def attach_request_and_sender_info message, sender_info
192
+ # here, instead of the ip, we need to report the first non-private 'X-Forwarded-For' Header if available.
193
+ # if not we return '-'
194
+ needed_header = extract_sender_ip
195
+ # I'm not sure if we should report the sender ip from the ActivityDtm
196
+ src = if needed_header
197
+ needed_header
198
+ else
199
+ sender_info.ip.length > 1 ? sender_info.ip : DEFAULT_METADATA
200
+ end
201
+ message << "src=#{ src }"
202
+ message << "port=#{ sender_info.port }"
203
+ end
204
+
205
+ def extract_ip_address
206
+ res = Socket.getifaddrs.reject do |ifaddr|
207
+ !ifaddr.addr.ipv4? ||
208
+ (ifaddr.flags & Socket::IFF_MULTICAST).zero? ||
209
+ ifaddr.name != 'en0' # rubocop:disable Security/Module/Name
210
+ end
211
+ return unless res.length.positive?
212
+
213
+ res[0].addr.ip_address
214
+ end
215
+
216
+ def extract_sender_ip
217
+ request_headers = context.activity.http_request.request_headers&.transform_keys(&:to_s)
218
+ request_headers['X-Forwarded-For']
219
+ end
220
+ end
221
+ end
222
+ end
@@ -51,14 +51,13 @@ module Contrast
51
51
  # deprecated and soon to be removed functionality. This method handles doing that by leveraging the standard
52
52
  # Kernel#warn approach
53
53
  def inform_deprecations
54
- # Ruby 2.5 is currently in security maintenance, meaning int is only receiving updates for security issues. It
55
- # will move to eol on 31 March 2021. As such, we can remove support for it in Q3. We'll begin the deprecation
56
- # warnings now so that customers have time to reach out if they'll be impacted.
57
- # TODO: RUBY-715 remove this part of the method, leaving it empty if there are no other deprecations, when we
58
- # drop 2.5 support.
59
- return unless RUBY_VERSION < '2.6.0'
54
+ # Ruby 2.6 will be dropped in april of 2022. We'll begin the deprecation warnings
55
+ # now so that customers have time to reach out if they'll be impacted.
56
+ # TODO: RUBY-1188 remove this part of the method, leaving it empty if there are no other deprecations, when we
57
+ # drop 2.6 support.
58
+ return unless RUBY_VERSION < '2.7.0'
60
59
 
61
- Kernel.warn('[Contrast Security] [DEPRECATION] Support for Ruby 2.5 will be removed in April 2021. '\
60
+ Kernel.warn('[Contrast Security] [DEPRECATION] Support for Ruby 2.6 will be removed in April 2022. '\
62
61
  'Please contact Customer Support prior if you require continued support.')
63
62
  end
64
63
 
@@ -59,15 +59,7 @@ module Contrast
59
59
  return @_connection_verified unless @_connection_verified.nil?
60
60
  return false if client.nil?
61
61
 
62
- # Before RUBY 2.7 there is no #ipaddr
63
- ipaddr = if RUBY_VERSION < '2.7.0'
64
- socket = TCPSocket.open(client.address, client.port)
65
- ipaddr = socket.peeraddr[3]
66
- socket.close
67
- ipaddr
68
- else
69
- client.ipaddr
70
- end
62
+ ipaddr = get_ipaddr(client)
71
63
  response = client.request(Net::HTTP::Get.new(client.address))
72
64
  verify_cert = client.address.to_s.include?('localhost') ||
73
65
  OpenSSL::SSL.verify_certificate_identity(client.peer_cert, client.address)
@@ -160,6 +152,17 @@ module Contrast
160
152
 
161
153
  @_proxy_enabled = Contrast::API.proxy_enabled? && !Contrast::API.proxy_url.nil?
162
154
  end
155
+
156
+ # Retrieve the IP address from the client.
157
+ #
158
+ # @param client [Net::HTTP]
159
+ # @return [String]
160
+ def get_ipaddr client
161
+ socket = TCPSocket.open(client.address, client.port)
162
+ ipaddr = socket.peeraddr[3]
163
+ socket.close
164
+ ipaddr
165
+ end
163
166
  end
164
167
  end
165
168
  end
@@ -63,10 +63,6 @@ module Contrast
63
63
  rescue StandardError => e
64
64
  # Anything else was our bad and we gotta catch that to allow for normal application flow
65
65
  logger.error('Unable to apply pre patch to method.', e)
66
- rescue Exception => e # rubocop:disable Lint/RescueException
67
- # This is something like NoMemoryError that we can't hope to handle. Nonetheless, shouldn't leak scope.
68
- exit_contrast_scope!
69
- raise e
70
66
  end
71
67
 
72
68
  # THIS IS CALLED FROM C. Do not change the signature lightly.
data/lib/contrast.rb CHANGED
@@ -21,10 +21,11 @@ class Object
21
21
  alias_method :cs__singleton_class, :singleton_class
22
22
  end
23
23
 
24
- if RUBY_VERSION >= '3.0.0'
24
+ if RUBY_VERSION >= '3.0.0' && RUBY_VERSION < '3.1.0'
25
25
  # This fixes Ruby 3.0 issues with Module#(some instance method) patching by preventing the prepending of
26
26
  # a JSON helper on protobuf load. String.instance_method(:+) is one of the most noticeable.
27
- # TODO: RUBY-1132 Remove this once Ruby 3 is fixed.
27
+ # This is fixed in Ruby 3.1.0
28
+ # TODO: RUBY-1132 Remove this once Ruby 3 support is dropped.
28
29
  # See bug here: https://bugs.ruby-lang.org/issues/17725
29
30
  class Class
30
31
  alias_method(:cs__orig_prepend, :prepend)
@@ -73,7 +74,7 @@ require 'contrast/utils/preflight_util'
73
74
  require 'contrast/utils/assess/sampling_util'
74
75
  require 'contrast/agent'
75
76
 
76
- if RUBY_VERSION >= '3.0.0'
77
+ if RUBY_VERSION >= '3.0.0' && RUBY_VERSION < '3.1.0'
77
78
  # Put prepend back as it was.
78
79
  Class.alias_method(:prepend, :cs__orig_prepend)
79
80
  Class.remove_method(:cs__orig_prepend)
data/ruby-agent.gemspec CHANGED
@@ -173,7 +173,7 @@ Gem::Specification.new do |spec|
173
173
  'Testing and Protection.'
174
174
  spec.homepage = 'https://www.contrastsecurity.com'
175
175
  spec.license = 'CONTRAST SECURITY (see license file)'
176
- spec.required_ruby_version = ['>= 2.6.0', '< 3.1.0']
176
+ spec.required_ruby_version = ['>= 2.6.0', '< 3.2.0']
177
177
 
178
178
  spec.bindir = 'exe'
179
179
  spec.executables = ['contrast_service']
@@ -1 +1 @@
1
- 2.27.3
1
+ 2.28.6
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: 5.1.0
4
+ version: 5.2.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: 2022-01-24 00:00:00.000000000 Z
16
+ date: 2022-02-22 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: bundler
@@ -617,19 +617,20 @@ executables:
617
617
  - contrast_service
618
618
  extensions:
619
619
  - ext/cs__common/extconf.rb
620
- - ext/cs__contrast_patch/extconf.rb
621
- - ext/cs__assess_yield_track/extconf.rb
620
+ - ext/cs__os_information/extconf.rb
621
+ - ext/cs__assess_basic_object/extconf.rb
622
+ - ext/cs__assess_kernel/extconf.rb
622
623
  - ext/cs__assess_hash/extconf.rb
623
- - ext/cs__assess_marshal_module/extconf.rb
624
+ - ext/cs__assess_yield_track/extconf.rb
624
625
  - ext/cs__assess_fiber_track/extconf.rb
625
- - ext/cs__assess_string_interpolation26/extconf.rb
626
- - ext/cs__assess_basic_object/extconf.rb
627
- - ext/cs__assess_array/extconf.rb
628
626
  - ext/cs__assess_regexp/extconf.rb
629
- - ext/cs__assess_kernel/extconf.rb
630
- - ext/cs__os_information/extconf.rb
631
627
  - ext/cs__assess_string/extconf.rb
628
+ - ext/cs__assess_array/extconf.rb
629
+ - ext/cs__contrast_patch/extconf.rb
630
+ - ext/cs__scope/extconf.rb
631
+ - ext/cs__assess_string_interpolation26/extconf.rb
632
632
  - ext/cs__assess_module/extconf.rb
633
+ - ext/cs__assess_marshal_module/extconf.rb
633
634
  extra_rdoc_files: []
634
635
  files:
635
636
  - ".clang-format"
@@ -687,6 +688,9 @@ files:
687
688
  - ext/cs__os_information/cs__os_information.c
688
689
  - ext/cs__os_information/cs__os_information.h
689
690
  - ext/cs__os_information/extconf.rb
691
+ - ext/cs__scope/cs__scope.c
692
+ - ext/cs__scope/cs__scope.h
693
+ - ext/cs__scope/extconf.rb
690
694
  - ext/extconf_common.rb
691
695
  - funchook/LICENSE
692
696
  - funchook/Makefile.in
@@ -879,16 +883,19 @@ files:
879
883
  - lib/contrast/agent/assess/rule/provider/hardcoded_key.rb
880
884
  - lib/contrast/agent/assess/rule/provider/hardcoded_password.rb
881
885
  - lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb
882
- - lib/contrast/agent/assess/rule/response/autocomplete_rule.rb
886
+ - lib/contrast/agent/assess/rule/response/auto_complete_rule.rb
883
887
  - lib/contrast/agent/assess/rule/response/base_rule.rb
884
- - lib/contrast/agent/assess/rule/response/cachecontrol_rule.rb
885
- - lib/contrast/agent/assess/rule/response/clickjacking_rule.rb
888
+ - lib/contrast/agent/assess/rule/response/body_rule.rb
889
+ - lib/contrast/agent/assess/rule/response/cache_control_header_rule.rb
890
+ - lib/contrast/agent/assess/rule/response/click_jacking_header_rule.rb
886
891
  - lib/contrast/agent/assess/rule/response/csp_header_insecure_rule.rb
887
892
  - lib/contrast/agent/assess/rule/response/csp_header_missing_rule.rb
893
+ - lib/contrast/agent/assess/rule/response/framework/rails_support.rb
894
+ - lib/contrast/agent/assess/rule/response/header_rule.rb
888
895
  - lib/contrast/agent/assess/rule/response/hsts_header_rule.rb
889
896
  - lib/contrast/agent/assess/rule/response/parameters_pollution_rule.rb
890
- - lib/contrast/agent/assess/rule/response/x_content_type_rule.rb
891
- - lib/contrast/agent/assess/rule/response/x_xss_protection_rule.rb
897
+ - lib/contrast/agent/assess/rule/response/x_content_type_header_rule.rb
898
+ - lib/contrast/agent/assess/rule/response/x_xss_protection_header_rule.rb
892
899
  - lib/contrast/agent/assess/tag.rb
893
900
  - lib/contrast/agent/assess/tracker.rb
894
901
  - lib/contrast/agent/at_exit_hook.rb
@@ -918,6 +925,7 @@ files:
918
925
  - lib/contrast/agent/patching/policy/policy.rb
919
926
  - lib/contrast/agent/patching/policy/policy_node.rb
920
927
  - lib/contrast/agent/patching/policy/trigger_node.rb
928
+ - lib/contrast/agent/protect/input_analyzer/input_analyzer.rb
921
929
  - lib/contrast/agent/protect/policy/applies_command_injection_rule.rb
922
930
  - lib/contrast/agent/protect/policy/applies_deserialization_rule.rb
923
931
  - lib/contrast/agent/protect/policy/applies_no_sqli_rule.rb
@@ -942,12 +950,18 @@ files:
942
950
  - lib/contrast/agent/protect/rule/sqli/default_sql_scanner.rb
943
951
  - lib/contrast/agent/protect/rule/sqli/mysql_sql_scanner.rb
944
952
  - lib/contrast/agent/protect/rule/sqli/postgres_sql_scanner.rb
953
+ - lib/contrast/agent/protect/rule/sqli/sqli_input_classification.rb
954
+ - lib/contrast/agent/protect/rule/sqli/sqli_worth_watching.rb
945
955
  - lib/contrast/agent/protect/rule/sqli/sqlite_sql_scanner.rb
946
956
  - lib/contrast/agent/protect/rule/unsafe_file_upload.rb
947
957
  - lib/contrast/agent/protect/rule/xss.rb
948
958
  - lib/contrast/agent/protect/rule/xxe.rb
949
959
  - lib/contrast/agent/protect/rule/xxe/entity_wrapper.rb
950
960
  - lib/contrast/agent/reaction_processor.rb
961
+ - lib/contrast/agent/reporting/input_analysis/input_analysis.rb
962
+ - lib/contrast/agent/reporting/input_analysis/input_analysis_result.rb
963
+ - lib/contrast/agent/reporting/input_analysis/input_type.rb
964
+ - lib/contrast/agent/reporting/input_analysis/score_level.rb
951
965
  - lib/contrast/agent/reporting/report.rb
952
966
  - lib/contrast/agent/reporting/reporter.rb
953
967
  - lib/contrast/agent/reporting/reporting_events/application_inventory.rb
@@ -956,16 +970,19 @@ files:
956
970
  - lib/contrast/agent/reporting/reporting_events/discovered_route.rb
957
971
  - lib/contrast/agent/reporting/reporting_events/finding.rb
958
972
  - lib/contrast/agent/reporting/reporting_events/finding_event.rb
973
+ - lib/contrast/agent/reporting/reporting_events/finding_event_object.rb
974
+ - lib/contrast/agent/reporting/reporting_events/finding_event_parent_object.rb
975
+ - lib/contrast/agent/reporting/reporting_events/finding_event_property.rb
976
+ - lib/contrast/agent/reporting/reporting_events/finding_event_signature.rb
959
977
  - lib/contrast/agent/reporting/reporting_events/finding_event_source.rb
960
- - lib/contrast/agent/reporting/reporting_events/finding_object.rb
978
+ - lib/contrast/agent/reporting/reporting_events/finding_event_stack.rb
979
+ - lib/contrast/agent/reporting/reporting_events/finding_event_taint_range.rb
961
980
  - lib/contrast/agent/reporting/reporting_events/finding_request.rb
962
- - lib/contrast/agent/reporting/reporting_events/finding_signature.rb
963
- - lib/contrast/agent/reporting/reporting_events/finding_stack.rb
964
- - lib/contrast/agent/reporting/reporting_events/finding_taint_range.rb
965
981
  - lib/contrast/agent/reporting/reporting_events/library_discovery.rb
966
982
  - lib/contrast/agent/reporting/reporting_events/library_usage_observation.rb
967
983
  - lib/contrast/agent/reporting/reporting_events/observed_library_usage.rb
968
984
  - lib/contrast/agent/reporting/reporting_events/observed_route.rb
985
+ - lib/contrast/agent/reporting/reporting_events/poll.rb
969
986
  - lib/contrast/agent/reporting/reporting_events/preflight.rb
970
987
  - lib/contrast/agent/reporting/reporting_events/preflight_message.rb
971
988
  - lib/contrast/agent/reporting/reporting_events/reporting_event.rb
@@ -1028,10 +1045,12 @@ files:
1028
1045
  - lib/contrast/api/decorators/application_startup.rb
1029
1046
  - lib/contrast/api/decorators/application_update.rb
1030
1047
  - lib/contrast/api/decorators/architecture_component.rb
1048
+ - lib/contrast/api/decorators/bot_blocker.rb
1031
1049
  - lib/contrast/api/decorators/finding.rb
1032
1050
  - lib/contrast/api/decorators/http_request.rb
1033
1051
  - lib/contrast/api/decorators/input_analysis.rb
1034
1052
  - lib/contrast/api/decorators/instrumentation_mode.rb
1053
+ - lib/contrast/api/decorators/ip_denylist.rb
1035
1054
  - lib/contrast/api/decorators/library.rb
1036
1055
  - lib/contrast/api/decorators/library_usage_update.rb
1037
1056
  - lib/contrast/api/decorators/message.rb
@@ -1044,6 +1063,7 @@ files:
1044
1063
  - lib/contrast/api/decorators/trace_taint_range.rb
1045
1064
  - lib/contrast/api/decorators/trace_taint_range_tags.rb
1046
1065
  - lib/contrast/api/decorators/user_input.rb
1066
+ - lib/contrast/api/decorators/virtual_patch.rb
1047
1067
  - lib/contrast/api/dtm.pb.rb
1048
1068
  - lib/contrast/api/settings.pb.rb
1049
1069
  - lib/contrast/components/agent.rb
@@ -1099,7 +1119,6 @@ files:
1099
1119
  - lib/contrast/extension/delegator.rb
1100
1120
  - lib/contrast/extension/extension.rb
1101
1121
  - lib/contrast/extension/inventory.rb
1102
- - lib/contrast/extension/kernel.rb
1103
1122
  - lib/contrast/extension/module.rb
1104
1123
  - lib/contrast/extension/protect.rb
1105
1124
  - lib/contrast/extension/protect/psych.rb
@@ -1121,6 +1140,7 @@ files:
1121
1140
  - lib/contrast/framework/sinatra/support.rb
1122
1141
  - lib/contrast/funchook/funchook.rb
1123
1142
  - lib/contrast/logger/application.rb
1143
+ - lib/contrast/logger/cef_log.rb
1124
1144
  - lib/contrast/logger/format.rb
1125
1145
  - lib/contrast/logger/log.rb
1126
1146
  - lib/contrast/logger/request.rb
@@ -1201,7 +1221,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
1201
1221
  version: 2.6.0
1202
1222
  - - "<"
1203
1223
  - !ruby/object:Gem::Version
1204
- version: 3.1.0
1224
+ version: 3.2.0
1205
1225
  required_rubygems_version: !ruby/object:Gem::Requirement
1206
1226
  requirements:
1207
1227
  - - ">="