contrast-agent 6.9.0 → 6.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/lib/contrast/agent/assess/rule/response/body_rule.rb +1 -1
  4. data/lib/contrast/agent/middleware.rb +4 -2
  5. data/lib/contrast/agent/protect/input_analyzer/input_analyzer.rb +76 -83
  6. data/lib/contrast/agent/protect/input_analyzer/worth_watching_analyzer.rb +40 -35
  7. data/lib/contrast/agent/protect/policy/applies_command_injection_rule.rb +2 -0
  8. data/lib/contrast/agent/protect/policy/applies_no_sqli_rule.rb +6 -3
  9. data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +3 -0
  10. data/lib/contrast/agent/protect/policy/applies_sqli_rule.rb +3 -0
  11. data/lib/contrast/agent/protect/policy/rule_applicator.rb +12 -0
  12. data/lib/contrast/agent/protect/rule/base.rb +19 -5
  13. data/lib/contrast/agent/protect/rule/base_service.rb +6 -0
  14. data/lib/contrast/agent/protect/rule/bot_blocker/bot_blocker_input_classification.rb +1 -1
  15. data/lib/contrast/agent/protect/rule/bot_blocker.rb +8 -0
  16. data/lib/contrast/agent/protect/rule/cmdi/cmdi_base_rule.rb +8 -0
  17. data/lib/contrast/agent/protect/rule/deserialization.rb +2 -2
  18. data/lib/contrast/agent/protect/rule/no_sqli.rb +24 -2
  19. data/lib/contrast/agent/protect/rule/path_traversal/path_traversal_input_classification.rb +1 -1
  20. data/lib/contrast/agent/protect/rule/path_traversal.rb +8 -0
  21. data/lib/contrast/agent/protect/rule/sqli/sqli_input_classification.rb +0 -1
  22. data/lib/contrast/agent/protect/rule/sqli.rb +6 -10
  23. data/lib/contrast/agent/protect/rule/unsafe_file_upload/unsafe_file_upload_input_classification.rb +6 -2
  24. data/lib/contrast/agent/protect/rule/unsafe_file_upload.rb +20 -0
  25. data/lib/contrast/agent/protect/rule/xss/reflected_xss_input_classification.rb +1 -1
  26. data/lib/contrast/agent/protect/rule/xss.rb +8 -0
  27. data/lib/contrast/agent/protect/rule/xxe.rb +2 -2
  28. data/lib/contrast/agent/protect/rule.rb +0 -3
  29. data/lib/contrast/agent/reporting/attack_result/user_input.rb +0 -1
  30. data/lib/contrast/agent/reporting/details/details.rb +0 -1
  31. data/lib/contrast/agent/reporting/input_analysis/input_analysis.rb +12 -0
  32. data/lib/contrast/agent/reporting/report.rb +1 -0
  33. data/lib/contrast/agent/reporting/reporter.rb +11 -10
  34. data/lib/contrast/agent/reporting/reporting_events/application_activity.rb +4 -5
  35. data/lib/contrast/agent/reporting/reporting_events/application_defend_activity.rb +13 -1
  36. data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_activity.rb +20 -5
  37. data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample.rb +0 -1
  38. data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample_activity.rb +5 -0
  39. data/lib/contrast/agent/reporting/reporting_events/application_defend_attacker_activity.rb +10 -1
  40. data/lib/contrast/agent/reporting/reporting_events/application_inventory.rb +2 -1
  41. data/lib/contrast/agent/reporting/reporting_events/application_reporting_event.rb +10 -0
  42. data/lib/contrast/agent/reporting/reporting_events/application_settings.rb +40 -0
  43. data/lib/contrast/agent/reporting/reporting_utilities/ng_response_extractor.rb +137 -0
  44. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +12 -4
  45. data/lib/contrast/agent/reporting/reporting_utilities/response_extractor.rb +100 -107
  46. data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +5 -4
  47. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +97 -63
  48. data/lib/contrast/agent/reporting/reporting_workers/application_server_worker.rb +46 -0
  49. data/lib/contrast/agent/reporting/reporting_workers/reporter_heartbeat.rb +51 -0
  50. data/lib/contrast/agent/reporting/reporting_workers/reporting_workers.rb +14 -0
  51. data/lib/contrast/agent/reporting/reporting_workers/server_settings_worker.rb +46 -0
  52. data/lib/contrast/agent/reporting/settings/assess.rb +14 -1
  53. data/lib/contrast/agent/reporting/settings/assess_rule.rb +18 -0
  54. data/lib/contrast/agent/reporting/settings/helpers.rb +4 -2
  55. data/lib/contrast/agent/reporting/settings/protect.rb +17 -12
  56. data/lib/contrast/agent/reporting/settings/protect_rule.rb +18 -0
  57. data/lib/contrast/agent/reporting/settings/protect_server_feature.rb +1 -1
  58. data/lib/contrast/agent/reporting/settings/sensitive_data_masking.rb +1 -1
  59. data/lib/contrast/agent/reporting/settings/virtual_patch.rb +56 -0
  60. data/lib/contrast/agent/reporting/settings/virtual_patch_condition.rb +47 -0
  61. data/lib/contrast/agent/request_context_extend.rb +20 -0
  62. data/lib/contrast/agent/telemetry/base.rb +11 -10
  63. data/lib/contrast/agent/telemetry/events/exceptions/obfuscate.rb +108 -103
  64. data/lib/contrast/agent/telemetry/events/startup_metrics_event.rb +1 -1
  65. data/lib/contrast/agent/thread_watcher.rb +16 -10
  66. data/lib/contrast/agent/version.rb +1 -1
  67. data/lib/contrast/agent.rb +12 -0
  68. data/lib/contrast/agent_lib/api/init.rb +1 -7
  69. data/lib/contrast/agent_lib/api/input_tracing.rb +2 -4
  70. data/lib/contrast/agent_lib/interface.rb +1 -16
  71. data/lib/contrast/agent_lib/interface_base.rb +52 -39
  72. data/lib/contrast/agent_lib/return_types/eval_result.rb +2 -2
  73. data/lib/contrast/components/assess.rb +26 -4
  74. data/lib/contrast/components/polling.rb +4 -1
  75. data/lib/contrast/components/settings.rb +46 -3
  76. data/lib/contrast/config/config.rb +2 -2
  77. data/lib/contrast/config/protect_rule_configuration.rb +1 -1
  78. data/lib/contrast/config/protect_rules_configuration.rb +1 -1
  79. data/lib/contrast/extension/assess/array.rb +3 -3
  80. data/lib/contrast/extension/assess/regexp.rb +2 -2
  81. data/lib/contrast/logger/aliased_logging.rb +48 -15
  82. data/lib/contrast/utils/input_classification_base.rb +21 -4
  83. data/lib/contrast/utils/routes_sent.rb +2 -2
  84. data/lib/contrast/utils/telemetry.rb +1 -1
  85. data/lib/contrast/utils/telemetry_client.rb +1 -1
  86. data/resources/protect/policy.json +8 -0
  87. data/ruby-agent.gemspec +1 -1
  88. metadata +28 -18
  89. data/lib/contrast/agent/protect/rule/http_method_tampering/http_method_tampering_input_classification.rb +0 -96
  90. data/lib/contrast/agent/protect/rule/http_method_tampering.rb +0 -83
  91. data/lib/contrast/agent/reporting/details/http_method_tempering_details.rb +0 -27
  92. data/lib/contrast/agent/reporting/reporter_heartbeat.rb +0 -47
  93. data/lib/contrast/agent/reporting/server_settings_worker.rb +0 -44
  94. data/lib/contrast/agent_lib/api/method_tempering.rb +0 -29
@@ -0,0 +1,137 @@
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
+ # This module will hold the methods for TS response conversion to settings objects. It is used for those
8
+ # endpoints which have NG in their prefix.
9
+ module NgResponseExtractor
10
+ private
11
+
12
+ # @param response_data [Hash]
13
+ # @param res [Contrast::Agent::Reporting::Response]
14
+ def ng_extract_assess response_data, res
15
+ assessments = response_data[:settings][:assessment]
16
+ return unless assessments
17
+
18
+ res.application_settings.assess.session_id = assessments[:session_id]
19
+ disabled = assessments[:disabledRules]
20
+ return unless disabled
21
+
22
+ disabled.each do |rule_id|
23
+ rule_setting = Contrast::Agent::Reporting::Settings::AssessRule.new.tap { |setting| setting.enable = false }
24
+ res.application_settings.assess.rule_settings[rule_id] = rule_setting
25
+ end
26
+ end
27
+
28
+ # @param response_data [Hash]
29
+ # @param res [Contrast::Agent::Reporting::Response]
30
+ def ng_extract_protect response_data, res
31
+ protect = response_data[:settings][:defend]
32
+ return unless protect
33
+
34
+ res.application_settings.protect.protection_rules = protect[:protectionRules]
35
+ protect[:virtualPatches]&.each do |patch_json|
36
+ res.application_settings.protect.virtual_patches <<
37
+ Contrast::Agent::Reporting::Settings::VirtualPatch.new(patch_json)
38
+ end
39
+ end
40
+
41
+ # @param response_data [Hash]
42
+ # @param res [Contrast::Agent::Reporting::Response]
43
+ def ng_extract_exclusions response_data, res
44
+ exclusions = response_data[:settings][:exceptions]
45
+ return unless exclusions
46
+
47
+ res.application_settings.exclusions.code_exclusions = exclusions[:codeExceptions]
48
+ res.application_settings.exclusions.input_exclusions = exclusions[:inputExceptions]
49
+ res.application_settings.exclusions.url_exclusions = exclusions[:urlExceptions]
50
+ end
51
+
52
+ # The responses we receive for feature and settings from TS have different
53
+ # place to store these reactions: body.reactions vs body.settings.reactions.
54
+ #
55
+ # @param response_data [Hash]
56
+ # @param res [Contrast::Agent::Reporting::Response]
57
+ def ng_extract_reactions response_data, res
58
+ res.reactions = response_data[:settings][:reactions] if response_data[:settings]
59
+ res.reactions = response_data[:reactions] if response_data[:features]
60
+ end
61
+
62
+ # This method is universal and used for both ng endpoint of feature settings and the new
63
+ # Server settings endpoint. Used in both build_feature_settings and build_server_settings.
64
+ # Passing the ng_ flag determines the use of the endpoint and response used because some of
65
+ # the response fields are with different names or do not exist: [enabled vs enable]
66
+ #
67
+ # @param response_data [Hash]
68
+ # @param res [Contrast::Agent::Reporting::Response]
69
+ def ng_extract_assess_features response_data, res
70
+ assess = response_data[:features][:assessment]
71
+ return unless assess
72
+
73
+ res.server_features.assess.enabled = assess[:enabled]
74
+ res.server_features.assess.sampling = assess[:sampling]
75
+ res.server_features.assess.sanitizers = assess[:sanitizers]
76
+ res.server_features.assess.validators = assess[:validators]
77
+ end
78
+
79
+ # @param response_data [Hash]
80
+ # @param res [Contrast::Agent::Reporting::Response]
81
+ def ng_extract_protect_features response_data, res
82
+ protect = response_data[:features][:defend]
83
+ return unless protect
84
+
85
+ res.server_features.protect.enabled = protect[:enabled]
86
+ res.server_features.protect.bot_blocker.enable = protect[:'bot-blocker']
87
+ res.server_features.protect.bot_blocker.bots = protect[:botBlockers]
88
+ ng_extract_syslog(response_data, res)
89
+ end
90
+
91
+ # @param response_data [Hash]
92
+ # @param res [Contrast::Agent::Reporting::Response]
93
+ def ng_extract_syslog response_data, res
94
+ return unless (syslog = response_data[:features][:defend][:syslog])
95
+
96
+ res.server_features.protect.syslog.assign_array(syslog, ng_: true)
97
+ end
98
+
99
+ # @param response_data [Hash]
100
+ # @param res [Contrast::Agent::Reporting::Response]
101
+ def ng_extract_protect_lists response_data, res
102
+ protect = response_data[:features][:defend]
103
+ return unless protect
104
+
105
+ res.server_features.protect.ip_allowlist = protect[:ipAllowlist]
106
+ res.server_features.protect.ip_denylist = protect[:ipDenylist]
107
+ res.server_features.protect.log_enhancers = protect[:logEnhancers]
108
+ res.server_features.protect.ng_rule_definition_list(protect[:ruleDefinitionList])
109
+ end
110
+
111
+ # Here we extract the rules and state for the sensitive data masking policy
112
+ # received from TS.
113
+ #
114
+ # @param response_data [Hash]
115
+ # @param res [Contrast::Agent::Reporting::Response]
116
+ def ng_extract_sensitive_data_policy response_data, res
117
+ return unless (sensitive_data = response_data[:settings][:sensitive_data_masking_policy])
118
+
119
+ res.application_settings.sensitive_data_masking.mask_http_body = sensitive_data[:mask_http_body]
120
+ res.application_settings.sensitive_data_masking.mask_attack_vector = sensitive_data[:mask_attack_vector]
121
+ res.application_settings.sensitive_data_masking.build_rules_form_settings(sensitive_data[:rules])
122
+ end
123
+
124
+ # Here we extract the log settings received from TS.
125
+ #
126
+ # @param response_data [Hash]
127
+ # @param res [Contrast::Agent::Reporting::Response]
128
+ def ng_extract_log_settings response_data, res
129
+ return unless (log_level = response_data[:logLevel])
130
+
131
+ res.server_features.log_level = log_level
132
+ res.server_features.log_file = response_data[:logFile] if response_data[:logFile]
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -11,6 +11,7 @@ require 'contrast/agent/reporting/reporting_utilities/reporter_client_utils'
11
11
  require 'contrast/agent/reporting/reporting_utilities/endpoints'
12
12
  require 'contrast/agent/reporting/reporting_utilities/headers'
13
13
  require 'contrast/agent/reporting/reporting_events/server_settings'
14
+ require 'contrast/agent/reporting/reporting_events/application_settings'
14
15
  require 'contrast/config/diagnostics'
15
16
 
16
17
  module Contrast
@@ -25,8 +26,17 @@ module Contrast
25
26
  include Contrast::Agent::Reporting::ReporterClientUtils
26
27
  include Contrast::Agent::Reporting::ResponseHandlerUtils
27
28
  include Contrast::Components::Logger::InstanceMethods
29
+
30
+ # @return [Array<Class>] events that may result in configuration changes
31
+ RECORDABLE_EVENTS = [
32
+ Contrast::Agent::Reporting::ServerSettings,
33
+ Contrast::Agent::Reporting::ApplicationSettings,
34
+ Contrast::Agent::Reporting::AgentStartup,
35
+ Contrast::Agent::Reporting::ApplicationStartup
36
+ ].cs__freeze
28
37
  SERVICE_NAME = 'Reporter'
29
38
  REPORT_CONFIG_WHEN = %w[200 304].cs__freeze
39
+
30
40
  def initialize
31
41
  @headers = Contrast::Agent::Reporting::Headers.new
32
42
  super()
@@ -60,7 +70,7 @@ module Contrast
60
70
  def send_event event, connection
61
71
  return unless connection
62
72
 
63
- logger.debug('Preparing to send reporting event', event_class: event.cs__class)
73
+ logger.debug('[Reporter] Preparing to send reporting event', event_class: event.cs__class)
64
74
 
65
75
  request = build_request(event)
66
76
  response = connection.request(request)
@@ -97,9 +107,7 @@ module Contrast
97
107
  def record_configuration response, event
98
108
  return unless response
99
109
  return unless REPORT_CONFIG_WHEN.include?(response_handler.last_response_code)
100
- return unless event&.cs__class == Contrast::Agent::Reporting::ServerSettings ||
101
- event&.cs__class == Contrast::Agent::Reporting::AgentStartup ||
102
- event&.cs__class == Contrast::Agent::Reporting::ApplicationStartup
110
+ return unless RECORDABLE_EVENTS.include?(event&.cs__class)
103
111
 
104
112
  logger.info('[Reporter Diagnostics] last response code:', response_code: response_handler.last_response_code)
105
113
  diagnostics.write_to_file
@@ -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 'contrast/agent/reporting/settings/assess_rule'
5
+ require 'contrast/agent/reporting/settings/protect_rule'
6
+
4
7
  module Contrast
5
8
  module Agent
6
9
  module Reporting
@@ -8,46 +11,9 @@ module Contrast
8
11
  module ResponseExtractor
9
12
  private
10
13
 
11
- # @param response_data [Hash]
12
- # @param res [Contrast::Agent::Reporting::Response]
13
- def extract_assess response_data, res
14
- assessments = response_data[:settings][:assessment]
15
- return unless assessments
16
-
17
- res.application_settings.assess.disabled_rules = assessments[:disabledRules]
18
- res.application_settings.assess.session_id = assessments[:session_id]
19
- end
20
-
21
- # @param response_data [Hash]
22
- # @param res [Contrast::Agent::Reporting::Response]
23
- def extract_protect response_data, res
24
- protect = response_data[:settings][:defend]
25
- return unless protect
26
-
27
- res.application_settings.protect.protection_rules = protect[:protectionRules]
28
- res.application_settings.protect.virtual_patches = protect[:virtualPatches]
29
- end
30
-
31
- # @param response_data [Hash]
32
- # @param res [Contrast::Agent::Reporting::Response]
33
- def extract_exclusions response_data, res
34
- exclusions = response_data[:settings][:exceptions]
35
- return unless exclusions
36
-
37
- res.application_settings.exclusions.code_exclusions = exclusions[:codeExceptions]
38
- res.application_settings.exclusions.input_exclusions = exclusions[:inputExceptions]
39
- res.application_settings.exclusions.url_exclusions = exclusions[:urlExceptions]
40
- end
41
-
42
- # The responses we receive for feature and settings from TS have different
43
- # place to store these reactions: body.reactions vs body.settings.reactions.
44
- #
45
- # @param response_data [Hash]
46
- # @param res [Contrast::Agent::Reporting::Response]
47
- def extract_reactions response_data, res
48
- res.reactions = response_data[:settings][:reactions] if response_data[:settings]
49
- res.reactions = response_data[:reactions] if response_data[:features]
50
- end
14
+ ##########################################
15
+ # Server Settings Parsing #
16
+ ##########################################
51
17
 
52
18
  # This method is universal and used for both ng endpoing of feature settings and the new
53
19
  # Server settings endpoint. Used in both build_feature_settings and build_server_settings.
@@ -56,13 +22,12 @@ module Contrast
56
22
  #
57
23
  # @param response_data [Hash]
58
24
  # @param res [Contrast::Agent::Reporting::Response]
59
- # @param ng_ [Boolean]
60
- def extract_assess_settings response_data, res, ng_: true
61
- assess = ng_ ? response_data[:features][:assessment] : response_data[:assess]
25
+ def extract_assess_server_settings response_data, res
26
+ assess = response_data[:assess]
62
27
  return unless assess
63
28
 
64
- res.server_features.assess.enabled = ng_ ? assess[:enabled] : assess[:enable]
65
- res.server_features.assess.report_stacktraces = assess[:report_stacktraces] unless ng_
29
+ res.server_features.assess.enabled = assess[:enable]
30
+ res.server_features.assess.report_stacktraces = assess[:report_stacktraces]
66
31
  res.server_features.assess.sampling = assess[:sampling]
67
32
  res.server_features.assess.sanitizers = assess[:sanitizers]
68
33
  res.server_features.assess.validators = assess[:validators]
@@ -70,58 +35,14 @@ module Contrast
70
35
 
71
36
  # @param response_data [Hash]
72
37
  # @param res [Contrast::Agent::Reporting::Response]
73
- def extract_protect_server_features response_data, res
74
- protect = response_data[:features][:defend]
75
- return unless protect
76
-
77
- res.server_features.protect.enabled = protect[:enabled]
78
- res.server_features.protect.bot_blocker.enable = protect[:'bot-blocker']
79
- res.server_features.protect.bot_blocker.bots = protect[:botBlockers]
80
- extract_syslog(response_data, res)
81
- end
82
-
83
- # @param response_data [Hash]
84
- # @param res [Contrast::Agent::Reporting::Response]
85
- def extract_syslog response_data, res
86
- return unless (syslog = response_data[:features][:defend][:syslog])
87
-
88
- res.server_features.protect.syslog.assign_array(syslog, ng_: true)
89
- end
90
-
91
- # @param response_data [Hash]
92
- # @param res [Contrast::Agent::Reporting::Response]
93
- def extract_protect_lists response_data, res
94
- protect = response_data[:features][:defend]
38
+ def extract_protect_server_settings response_data, res
39
+ protect = response_data[:protect]
95
40
  return unless protect
96
41
 
97
- res.server_features.protect.ip_allowlist = protect[:ipAllowlist]
98
- res.server_features.protect.ip_denylist = protect[:ipDenylist]
99
- res.server_features.protect.log_enhancers = protect[:logEnhancers]
100
- res.server_features.protect.rule_definition_list = protect[:ruleDefinitionList]
101
- end
102
-
103
- # Here we extract the rules and state for the sensitive data masking policy
104
- # received from TS.
105
- #
106
- # @param response_data [Hash]
107
- # @param res [Contrast::Agent::Reporting::Response]
108
- def extract_sensitive_data_policy response_data, res
109
- return unless (sensitive_data = response_data[:settings][:sensitive_data_masking_policy])
110
-
111
- res.application_settings.sensitive_data_masking.mask_http_body = sensitive_data[:mask_http_body]
112
- res.application_settings.sensitive_data_masking.mask_attack_vector = sensitive_data[:mask_attack_vector]
113
- res.application_settings.sensitive_data_masking.build_rules_form_settings(sensitive_data[:rules])
114
- end
115
-
116
- # Here we extract the log settings received from TS.
117
- #
118
- # @param response_data [Hash]
119
- # @param res [Contrast::Agent::Reporting::Response]
120
- def extract_log_settings response_data, res
121
- return unless (log_level = response_data[:logLevel])
122
-
123
- res.server_features.log_level = log_level
124
- res.server_features.log_file = response_data[:logFile] if response_data[:logFile]
42
+ res.server_features.protect.enabled = protect[:enable]
43
+ res.server_features.protect.observability = protect[:observability]
44
+ res.server_features.protect.log_enhancers = protect[:log_enhancers]
45
+ update_protect_rules(protect, res)
125
46
  end
126
47
 
127
48
  # This method is used with ServerSettings as we expect to have data for
@@ -147,18 +68,6 @@ module Contrast
147
68
  res.server_features.security_logger.syslog.assign_array(response_data[:security_logger][:syslog], ng_: false)
148
69
  end
149
70
 
150
- # @param response_data [Hash]
151
- # @param res [Contrast::Agent::Reporting::Response]
152
- def extract_protect_server_settings response_data, res
153
- protect = response_data[:protect]
154
- return unless protect
155
-
156
- res.server_features.protect.enabled = protect[:enable]
157
- res.server_features.protect.observability = protect[:observability]
158
- res.server_features.protect.log_enhancers = protect[:log_enhancers]
159
- update_protect_rules(protect, res)
160
- end
161
-
162
71
  # @param protect [Hash] response data
163
72
  # @param res [Contrast::Agent::Reporting::Response]
164
73
  def update_protect_rules protect, res
@@ -170,6 +79,90 @@ module Contrast
170
79
  res.server_features.protect.bot_blocker.bots = rules[:bot_blocker][:bots]
171
80
  res.server_features.protect.rules_to_definition_list(rules)
172
81
  end
82
+
83
+ ##########################################
84
+ # Application Settings Parsing #
85
+ ##########################################
86
+
87
+ # @param response_data [Hash]
88
+ # @param res [Contrast::Agent::Reporting::Response]
89
+ def extract_assess_application_settings response_data, res
90
+ assess = response_data[:assess]
91
+ return unless assess
92
+
93
+ assess.each_pair do |rule_id, value|
94
+ rule_setting =
95
+ Contrast::Agent::Reporting::Settings::AssessRule.new.tap { |setting| setting.enable = value[:enable] }
96
+ res.application_settings.assess.rule_settings[rule_id.to_s] = rule_setting
97
+ end
98
+
99
+ # This endpoint can never give us session_id, so we dont need to set it here
100
+ # res.application_settings.assess.session_id
101
+ end
102
+
103
+ # @param response_data [Hash]
104
+ # @param res [Contrast::Agent::Reporting::Response]
105
+ def extract_protect_application_settings response_data, res
106
+ protect = response_data[:protect]
107
+ return unless protect
108
+
109
+ rules = protect[:rules]
110
+ rules&.each_pair do |rule_id, value|
111
+ rule_setting =
112
+ Contrast::Agent::Reporting::Settings::ProtectRule.new.tap { |setting| setting.mode = value[:mode] }
113
+ res.application_settings.protect.rule_settings[rule_id.to_s] = rule_setting
114
+ end
115
+ protect[:'virtual-patches']&.each do |patch_json|
116
+ res.application_settings.protect.virtual_patches <<
117
+ Contrast::Agent::Reporting::Settings::VirtualPatch.new(patch_json)
118
+ end
119
+ end
120
+
121
+ # @param response_data [Hash]
122
+ # @param res [Contrast::Agent::Reporting::Response]
123
+ def extract_exclusions response_data, res
124
+ exclusions = response_data[:exclusions]
125
+ return unless exclusions
126
+
127
+ res.application_settings.exclusions.code_exclusions = exclusions[:code]
128
+ res.application_settings.exclusions.url_exclusions = exclusions[:url]
129
+ extract_input_exclusions(response_data[:exclusions], res)
130
+ end
131
+
132
+ # Input exclusions between NG and non-NG are different, so need to be cast separately.
133
+ #
134
+ # @param exclusions [Hash]
135
+ # @param res [Contrast::Agent::Reporting::Response]
136
+ def extract_input_exclusions exclusions, res
137
+ res.application_settings.exclusions.input_exclusions = []
138
+ exclusions[:input].each do |exclusion_details|
139
+ input_exclusion = Contrast::Agent::Reporting::Settings::InputExclusion.new
140
+ input_exclusion.name = exclusion_details[:name]
141
+ input_exclusion.modes = exclusion_details[:modes]
142
+ input_exclusion.assess_rules = exclusion_details[:assess_rules]
143
+ input_exclusion.protect_rules = exclusion_details[:protect_rules]
144
+ input_exclusion.input_name = exclusion_details[:name]
145
+ input_exclusion.input_type = exclusion_details[:type]
146
+ input_exclusion.urls = exclusion_details[:urls]
147
+ res.application_settings.exclusions.input_exclusions << exclusion
148
+ end
149
+ end
150
+
151
+ # @param response_data [Hash]
152
+ # @param res [Contrast::Agent::Reporting::Response]
153
+ def extract_sensitive_data_policy response_data, res
154
+ return unless (sensitive_data = response_data[:sensitive_data_masking_policy])
155
+
156
+ res.application_settings.sensitive_data_masking.mask_http_body = sensitive_data[:mask_http_body]
157
+ res.application_settings.sensitive_data_masking.mask_attack_vector = sensitive_data[:mask_attack_vector]
158
+ res.application_settings.sensitive_data_masking.build_rules_form_settings(sensitive_data[:rules])
159
+ end
160
+
161
+ # @param response_data [Hash]
162
+ # @param res [Contrast::Agent::Reporting::Response]
163
+ def extract_reactions response_data, res
164
+ res.reactions = response_data[:reactions]
165
+ end
173
166
  end
174
167
  end
175
168
  end
@@ -14,6 +14,7 @@ module Contrast
14
14
  class ResponseHandler
15
15
  include Contrast::Components::Logger::InstanceMethods
16
16
  include Contrast::Agent::Reporting::ResponseHandlerUtils
17
+
17
18
  # 15 min
18
19
  TIMEOUT = 900.cs__freeze
19
20
 
@@ -23,7 +24,7 @@ module Contrast
23
24
  # @param event [Contrast::Agent::Reporting::ReportingEvent] The event sent to TeamServer.
24
25
  # @return response [Net::HTTP::Response, nil]
25
26
  def process response, event
26
- logger.debug('Reporter Received a response')
27
+ logger.debug('[Reporter] Received a response')
27
28
  return unless analyze_response?(response)
28
29
 
29
30
  # Handle the response body and obtain server_features or app_settings
@@ -100,7 +101,7 @@ module Contrast
100
101
  # @param error_message [String, nil] Error message if any received.
101
102
  def suspend_reporting message, timeout, error_message
102
103
  @_timeout = timeout || Contrast::Agent::Reporting::ResponseHandler::TIMEOUT
103
- log_debug_msg(message, timeout: @_timeout, error_message: error_message || 'none')
104
+ log_error_msg(message, timeout: @_timeout, error_message: error_message || 'none')
104
105
  @_sleep = true
105
106
  end
106
107
 
@@ -108,8 +109,8 @@ module Contrast
108
109
  #
109
110
  # @param message [String] Message to log
110
111
  # @param info_hash [Hash] information about the context to log.
111
- def log_debug_msg message, info_hash
112
- logger.debug(message, info_hash)
112
+ def log_error_msg message, info_hash
113
+ logger.error(message, info_hash)
113
114
  end
114
115
  end
115
116
  end