contrast-agent 6.6.5 → 6.7.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 (150) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.gitmodules +0 -3
  4. data/ext/cs__scope/cs__scope.c +1 -1
  5. data/lib/contrast/agent/assess/contrast_event.rb +2 -24
  6. data/lib/contrast/agent/assess/events/source_event.rb +7 -61
  7. data/lib/contrast/agent/assess/finalizers/hash.rb +11 -0
  8. data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +0 -55
  9. data/lib/contrast/agent/assess/policy/policy_node.rb +3 -3
  10. data/lib/contrast/agent/assess/policy/policy_node_utils.rb +0 -1
  11. data/lib/contrast/agent/assess/policy/propagation_node.rb +4 -4
  12. data/lib/contrast/agent/assess/policy/source_method.rb +24 -1
  13. data/lib/contrast/agent/assess/policy/trigger/reflected_xss.rb +7 -5
  14. data/lib/contrast/agent/assess/policy/trigger/xpath.rb +6 -1
  15. data/lib/contrast/agent/assess/policy/trigger_method.rb +36 -132
  16. data/lib/contrast/agent/assess/policy/trigger_node.rb +3 -3
  17. data/lib/contrast/agent/assess/property/evented.rb +2 -12
  18. data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +42 -84
  19. data/lib/contrast/agent/assess/rule/response/base_rule.rb +11 -27
  20. data/lib/contrast/agent/assess/rule/response/body_rule.rb +1 -3
  21. data/lib/contrast/agent/assess/rule/response/cache_control_header_rule.rb +77 -62
  22. data/lib/contrast/agent/assess/rule/response/csp_header_insecure_rule.rb +1 -1
  23. data/lib/contrast/agent/assess/rule/response/framework/rails_support.rb +6 -1
  24. data/lib/contrast/agent/assess/rule/response/header_rule.rb +5 -5
  25. data/lib/contrast/agent/assess/rule/response/hsts_header_rule.rb +1 -1
  26. data/lib/contrast/agent/assess/rule/response/x_xss_protection_header_rule.rb +1 -1
  27. data/lib/contrast/agent/assess/tracker.rb +1 -7
  28. data/lib/contrast/agent/excluder.rb +206 -0
  29. data/lib/contrast/agent/exclusion_matcher.rb +6 -0
  30. data/lib/contrast/agent/inventory/database_config.rb +6 -10
  31. data/lib/contrast/agent/protect/policy/applies_command_injection_rule.rb +4 -0
  32. data/lib/contrast/agent/protect/policy/applies_sqli_rule.rb +1 -0
  33. data/lib/contrast/agent/protect/rule/base.rb +49 -5
  34. data/lib/contrast/agent/protect/rule/base_service.rb +1 -0
  35. data/lib/contrast/agent/protect/rule/cmd_injection.rb +18 -105
  36. data/lib/contrast/agent/protect/rule/cmdi/cmdi_backdoors.rb +129 -0
  37. data/lib/contrast/agent/protect/rule/cmdi/cmdi_base_rule.rb +169 -0
  38. data/lib/contrast/agent/protect/rule/deserialization.rb +2 -1
  39. data/lib/contrast/agent/protect/rule/sqli/sqli_base_rule.rb +51 -0
  40. data/lib/contrast/agent/protect/rule/sqli/sqli_semantic/sqli_dangerous_functions.rb +67 -0
  41. data/lib/contrast/agent/protect/rule/sqli.rb +6 -31
  42. data/lib/contrast/agent/protect/rule/xxe.rb +2 -0
  43. data/lib/contrast/agent/protect/rule.rb +3 -1
  44. data/lib/contrast/agent/reporting/attack_result/rasp_rule_sample.rb +6 -0
  45. data/lib/contrast/agent/reporting/details/sqli_dangerous_functions.rb +22 -0
  46. data/lib/contrast/agent/reporting/reporter.rb +1 -2
  47. data/lib/contrast/agent/reporting/reporting_events/agent_startup.rb +2 -2
  48. data/lib/contrast/agent/reporting/reporting_events/application_activity.rb +1 -4
  49. data/lib/contrast/agent/reporting/reporting_events/application_startup.rb +1 -1
  50. data/lib/contrast/agent/reporting/reporting_events/architecture_component.rb +0 -23
  51. data/lib/contrast/agent/reporting/reporting_events/finding.rb +19 -49
  52. data/lib/contrast/agent/reporting/reporting_events/finding_event.rb +12 -9
  53. data/lib/contrast/agent/reporting/reporting_events/finding_event_signature.rb +1 -1
  54. data/lib/contrast/agent/reporting/reporting_events/finding_event_source.rb +23 -21
  55. data/lib/contrast/agent/reporting/reporting_events/finding_event_stack.rb +5 -18
  56. data/lib/contrast/agent/reporting/reporting_events/finding_event_taint_range.rb +1 -0
  57. data/lib/contrast/{api/decorators/trace_taint_range_tags.rb → agent/reporting/reporting_events/finding_event_taint_range_tags.rb} +7 -6
  58. data/lib/contrast/agent/reporting/reporting_events/finding_request.rb +1 -1
  59. data/lib/contrast/agent/reporting/reporting_events/library_usage_observation.rb +1 -1
  60. data/lib/contrast/agent/reporting/reporting_events/observed_route.rb +2 -2
  61. data/lib/contrast/agent/reporting/reporting_events/preflight_message.rb +10 -14
  62. data/lib/contrast/agent/reporting/reporting_events/reporting_event.rb +11 -0
  63. data/lib/contrast/agent/reporting/reporting_events/route_coverage.rb +3 -1
  64. data/lib/contrast/agent/reporting/reporting_events/route_discovery.rb +11 -23
  65. data/lib/contrast/agent/reporting/reporting_events/route_discovery_observation.rb +8 -26
  66. data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +1 -1
  67. data/lib/contrast/agent/reporting/reporting_utilities/build_preflight.rb +4 -7
  68. data/lib/contrast/agent/reporting/reporting_utilities/headers.rb +1 -1
  69. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +3 -3
  70. data/lib/contrast/agent/request.rb +2 -2
  71. data/lib/contrast/agent/request_context.rb +8 -20
  72. data/lib/contrast/agent/request_context_extend.rb +15 -36
  73. data/lib/contrast/agent/request_handler.rb +0 -8
  74. data/lib/contrast/agent/response.rb +0 -18
  75. data/lib/contrast/agent/telemetry/events/event.rb +1 -1
  76. data/lib/contrast/agent/telemetry/events/metric_event.rb +1 -1
  77. data/lib/contrast/agent/telemetry/events/startup_metrics_event.rb +3 -3
  78. data/lib/contrast/agent/version.rb +1 -1
  79. data/lib/contrast/api/communication/messaging_queue.rb +2 -3
  80. data/lib/contrast/api/communication/socket_client.rb +4 -4
  81. data/lib/contrast/api/communication/speedracer.rb +4 -8
  82. data/lib/contrast/api/decorators/agent_startup.rb +5 -6
  83. data/lib/contrast/api/decorators/application_settings.rb +2 -1
  84. data/lib/contrast/api/decorators/application_startup.rb +6 -6
  85. data/lib/contrast/api/decorators/message.rb +0 -4
  86. data/lib/contrast/api/decorators/rasp_rule_sample.rb +0 -6
  87. data/lib/contrast/api/decorators.rb +0 -6
  88. data/lib/contrast/api/dtm.pb.rb +0 -489
  89. data/lib/contrast/components/agent.rb +16 -12
  90. data/lib/contrast/components/api.rb +10 -10
  91. data/lib/contrast/components/app_context.rb +3 -3
  92. data/lib/contrast/components/app_context_extend.rb +1 -1
  93. data/lib/contrast/components/assess.rb +92 -38
  94. data/lib/contrast/components/assess_rules.rb +36 -0
  95. data/lib/contrast/components/config.rb +54 -12
  96. data/lib/contrast/components/contrast_service.rb +8 -8
  97. data/lib/contrast/components/heap_dump.rb +1 -1
  98. data/lib/contrast/components/protect.rb +5 -5
  99. data/lib/contrast/components/ruby_component.rb +81 -0
  100. data/lib/contrast/components/sampling.rb +1 -1
  101. data/lib/contrast/components/security_logger.rb +23 -0
  102. data/lib/contrast/components/service.rb +55 -0
  103. data/lib/contrast/components/settings.rb +12 -4
  104. data/lib/contrast/config/base_configuration.rb +1 -1
  105. data/lib/contrast/config/protect_rules_configuration.rb +17 -3
  106. data/lib/contrast/config/server_configuration.rb +1 -1
  107. data/lib/contrast/config.rb +0 -6
  108. data/lib/contrast/configuration.rb +81 -17
  109. data/lib/contrast/extension/assess/exec_trigger.rb +3 -1
  110. data/lib/contrast/extension/assess/marshal.rb +3 -2
  111. data/lib/contrast/extension/assess/string.rb +0 -1
  112. data/lib/contrast/extension/extension.rb +1 -1
  113. data/lib/contrast/framework/base_support.rb +0 -5
  114. data/lib/contrast/framework/grape/support.rb +1 -23
  115. data/lib/contrast/framework/manager.rb +0 -10
  116. data/lib/contrast/framework/rails/support.rb +5 -58
  117. data/lib/contrast/framework/sinatra/support.rb +2 -21
  118. data/lib/contrast/logger/cef_log.rb +21 -3
  119. data/lib/contrast/logger/log.rb +1 -11
  120. data/lib/contrast/tasks/config.rb +4 -2
  121. data/lib/contrast/utils/assess/event_limit_utils.rb +5 -8
  122. data/lib/contrast/utils/assess/trigger_method_utils.rb +10 -18
  123. data/lib/contrast/utils/findings.rb +6 -5
  124. data/lib/contrast/utils/hash_digest.rb +9 -24
  125. data/lib/contrast/utils/hash_digest_extend.rb +6 -6
  126. data/lib/contrast/utils/invalid_configuration_util.rb +21 -58
  127. data/lib/contrast/utils/log_utils.rb +32 -8
  128. data/lib/contrast/utils/net_http_base.rb +2 -2
  129. data/lib/contrast/utils/patching/policy/patch_utils.rb +3 -2
  130. data/lib/contrast/utils/stack_trace_utils.rb +0 -25
  131. data/lib/contrast/utils/string_utils.rb +9 -0
  132. data/lib/contrast/utils/telemetry_client.rb +13 -7
  133. data/lib/contrast.rb +5 -10
  134. metadata +22 -28
  135. data/lib/contrast/agent/reporting/reporting_events/trace_event_source.rb +0 -30
  136. data/lib/contrast/agent/reporting/reporting_utilities/dtm_message.rb +0 -36
  137. data/lib/contrast/api/decorators/activity.rb +0 -33
  138. data/lib/contrast/api/decorators/architecture_component.rb +0 -36
  139. data/lib/contrast/api/decorators/finding.rb +0 -29
  140. data/lib/contrast/api/decorators/route_coverage.rb +0 -91
  141. data/lib/contrast/api/decorators/trace_event.rb +0 -120
  142. data/lib/contrast/api/decorators/trace_event_object.rb +0 -63
  143. data/lib/contrast/api/decorators/trace_event_signature.rb +0 -69
  144. data/lib/contrast/api/decorators/trace_taint_range.rb +0 -52
  145. data/lib/contrast/config/assess_configuration.rb +0 -93
  146. data/lib/contrast/config/assess_rules_configuration.rb +0 -32
  147. data/lib/contrast/config/root_configuration.rb +0 -90
  148. data/lib/contrast/config/ruby_configuration.rb +0 -81
  149. data/lib/contrast/config/service_configuration.rb +0 -49
  150. data/lib/contrast/utils/preflight_util.rb +0 -13
@@ -4,7 +4,10 @@
4
4
  require 'rubygems/version'
5
5
  require 'contrast/agent/rule_set'
6
6
  require 'contrast/components/logger'
7
+ require 'contrast/components/security_logger'
7
8
  require 'contrast/components/heap_dump'
9
+ require 'contrast/components/service'
10
+ require 'contrast/components/ruby_component'
8
11
 
9
12
  module Contrast
10
13
  module Components
@@ -21,9 +24,10 @@ module Contrast
21
24
  @_enable = hsh[:enable]
22
25
  @_start_bundled_service = hsh[:start_bundled_service]
23
26
  @_omit_body = hsh[:omit_body]
24
- @_service = Contrast::Config::ServiceConfiguration.new(hsh[:service])
27
+ @_service = Contrast::Components::Service::Interface.new(hsh[:service])
25
28
  @_logger = Contrast::Components::Logger::Interface.new(hsh[:logger])
26
- @_ruby = Contrast::Config::RubyConfiguration.new(hsh[:ruby])
29
+ @_security_logger = Contrast::Components::SecurityLogger::Interface.new(hsh[:security_logger])
30
+ @_ruby = Contrast::Components::Ruby::Interface.new(hsh[:ruby])
27
31
  @_heap_dump = Contrast::Components::HeapDump::Interface.new(hsh[:heap_dump])
28
32
  end
29
33
 
@@ -35,7 +39,7 @@ module Contrast
35
39
  def service
36
40
  return @_service unless @_service.nil?
37
41
 
38
- @_service = Contrast::Config::ServiceConfiguration.new
42
+ @_service = Contrast::Components::Service::Interface.new
39
43
  end
40
44
 
41
45
  def logger
@@ -44,10 +48,16 @@ module Contrast
44
48
  @_logger = Contrast::Components::Logger::Interface.new
45
49
  end
46
50
 
51
+ def security_logger
52
+ return @_security_logger unless @_security_logger.nil?
53
+
54
+ @_security_logger = Contrast::Components::SecurityLogger::Interface.new
55
+ end
56
+
47
57
  def ruby
48
58
  return @_ruby unless @_ruby.nil?
49
59
 
50
- @_ruby = Contrast::Config::RubyConfiguration.new
60
+ @_ruby = Contrast::Components::Ruby::Interface.new
51
61
  end
52
62
 
53
63
  def heap_dump
@@ -57,7 +67,7 @@ module Contrast
57
67
  end
58
68
 
59
69
  def enabled?
60
- @_enable = !false?(::Contrast::CONFIG.root.enable) if @_enable.nil?
70
+ @_enable = !false?(::Contrast::CONFIG.enable) if @_enable.nil?
61
71
  @_enable
62
72
  end
63
73
 
@@ -87,12 +97,6 @@ module Contrast
87
97
  !false?(ruby.propagate_yield)
88
98
  end
89
99
 
90
- def interpolation_enabled?
91
- return @_interpolation_enabled unless @_interpolation_enabled.nil?
92
-
93
- @_interpolation_enabled = !false?(::Contrast::CONFIG.root.agent.ruby.interpolate)
94
- end
95
-
96
100
  def omit_body?
97
101
  @_omit_body
98
102
  end
@@ -108,7 +112,7 @@ module Contrast
108
112
  def skip_instrumentation? loaded_module_name
109
113
  return true unless loaded_module_name
110
114
 
111
- loaded_module_name.start_with?(*::Contrast::CONFIG.root.agent.ruby.uninstrument_namespace)
115
+ loaded_module_name.start_with?(*::Contrast::CONFIG.agent.ruby.uninstrument_namespace)
112
116
  end
113
117
 
114
118
  # Insert ourselves into the application, keeping our middleware at the outermost layer of the onion
@@ -66,7 +66,7 @@ module Contrast
66
66
 
67
67
  def api_url
68
68
  @_api_url ||= begin
69
- tmp = Contrast::CONFIG.root.api.url
69
+ tmp = Contrast::CONFIG.api.url
70
70
  tmp += '/Contrast' unless tmp.end_with?('/Contrast')
71
71
  tmp
72
72
  end
@@ -75,7 +75,7 @@ module Contrast
75
75
  def proxy_enable
76
76
  return @_proxy_enable unless @_proxy_enable.nil?
77
77
 
78
- @_proxy_enable = true?(::Contrast::CONFIG.root.api.proxy.enable)
78
+ @_proxy_enable = true?(::Contrast::CONFIG.api.proxy.enable)
79
79
  end
80
80
 
81
81
  def proxy_url
@@ -85,39 +85,39 @@ module Contrast
85
85
  def request_audit_enable
86
86
  return @_request_audit_enable unless @_request_audit_enable.nil?
87
87
 
88
- @_request_audit_enable = true?(::Contrast::CONFIG.root.api.request_audit.enable)
88
+ @_request_audit_enable = true?(::Contrast::CONFIG.api.request_audit.enable)
89
89
  end
90
90
 
91
91
  def request_audit_requests
92
92
  return @_request_audit_requests unless @_request_audit_requests.nil?
93
93
 
94
- @_request_audit_requests = true?(::Contrast::CONFIG.root.api.request_audit.requests)
94
+ @_request_audit_requests = true?(::Contrast::CONFIG.api.request_audit.requests)
95
95
  end
96
96
 
97
97
  def request_audit_responses
98
98
  return @_request_audit_responses unless @_request_audit_responses.nil?
99
99
 
100
- @_request_audit_responses = true?(::Contrast::CONFIG.root.api.request_audit.responses)
100
+ @_request_audit_responses = true?(::Contrast::CONFIG.api.request_audit.responses)
101
101
  end
102
102
 
103
103
  def request_audit_path
104
- @_request_audit_path ||= ::Contrast::CONFIG.root.api.request_audit.path.to_s
104
+ @_request_audit_path ||= ::Contrast::CONFIG.api.request_audit.path.to_s
105
105
  end
106
106
 
107
107
  def certification_enable
108
- @_certification_enable ||= certification_truly_enabled?(::Contrast::CONFIG.root.api.certificate)
108
+ @_certification_enable ||= certification_truly_enabled?(::Contrast::CONFIG.api.certificate)
109
109
  end
110
110
 
111
111
  def certification_ca_file
112
- @_certification_ca_file ||= ::Contrast::CONFIG.root.api.certificate.ca_file
112
+ @_certification_ca_file ||= ::Contrast::CONFIG.api.certificate.ca_file
113
113
  end
114
114
 
115
115
  def certification_cert_file
116
- @_certification_cert_file ||= ::Contrast::CONFIG.root.api.certificate.cert_file
116
+ @_certification_cert_file ||= ::Contrast::CONFIG.api.certificate.cert_file
117
117
  end
118
118
 
119
119
  def certification_key_file
120
- @_certification_key_file ||= ::Contrast::CONFIG.root.api.certificate.key_file
120
+ @_certification_key_file ||= ::Contrast::CONFIG.api.certificate.key_file
121
121
  end
122
122
 
123
123
  private
@@ -83,7 +83,7 @@ module Contrast
83
83
 
84
84
  def server_type
85
85
  @_server_type ||= begin
86
- tmp = ::Contrast::CONFIG.root.server.type
86
+ tmp = ::Contrast::CONFIG.server.type
87
87
  tmp = Contrast::Agent.framework_manager.server_type unless Contrast::Utils::StringUtils.present?(tmp)
88
88
  tmp
89
89
  end
@@ -118,7 +118,7 @@ module Contrast
118
118
 
119
119
  def server_name
120
120
  @_server_name ||= begin
121
- tmp = ::Contrast::CONFIG.root.server.name # rubocop:disable Security/Module/Name
121
+ tmp = ::Contrast::CONFIG.server.name # rubocop:disable Security/Module/Name
122
122
  tmp = Socket.gethostname unless Contrast::Utils::StringUtils.present?(tmp)
123
123
  tmp = Contrast::Utils::StringUtils.force_utf8(tmp)
124
124
  Contrast::Utils::StringUtils.truncate(tmp, DEFAULT_SERVER_NAME)
@@ -129,7 +129,7 @@ module Contrast
129
129
 
130
130
  def server_path
131
131
  @_server_path ||= begin
132
- tmp = ::Contrast::CONFIG.root.server.path
132
+ tmp = ::Contrast::CONFIG.server.path
133
133
  tmp = Dir.pwd unless Contrast::Utils::StringUtils.present?(tmp)
134
134
  Contrast::Utils::StringUtils.truncate(tmp, DEFAULT_SERVER_PATH)
135
135
  rescue StandardError
@@ -71,7 +71,7 @@ module Contrast
71
71
  end
72
72
 
73
73
  def disabled_agent_rake_tasks
74
- ::Contrast::CONFIG.root.agent.ruby.disabled_agent_rake_tasks
74
+ ::Contrast::CONFIG.agent.ruby.disabled_agent_rake_tasks
75
75
  end
76
76
  end
77
77
  end
@@ -3,7 +3,7 @@
3
3
 
4
4
  require 'contrast/components/base'
5
5
  require 'contrast/components/config'
6
- require 'contrast/components/settings'
6
+ require 'contrast/components/assess_rules'
7
7
 
8
8
  module Contrast
9
9
  module Components
@@ -12,9 +12,85 @@ module Contrast
12
12
  # for access of the values contained in its
13
13
  # parent_configuration_spec.yaml.
14
14
  # Specifically, this allows for querying the state of the Assess product.
15
- class Interface
15
+ class Interface # rubocop:disable Metrics/ClassLength
16
16
  include Contrast::Components::ComponentBase
17
17
 
18
+ # @return [String, nil]
19
+ attr_accessor :tags
20
+ # @return [Boolean, nil]
21
+ attr_accessor :enable
22
+ # @return [Array, nil]
23
+ attr_writer :enable_scan_response, :enable_dynamic_sources, :sampling, :rules, :stacktraces
24
+
25
+ DEFAULT_STACKTRACES = 'ALL'
26
+ DEFAULT_MAX_SOURCE_EVENTS = 50_000
27
+ DEFAULT_MAX_PROPAGATION_EVENTS = 50_000
28
+ DEFAULT_MAX_RULE_REPORTED = 100
29
+ DEFAULT_MAX_RULE_TIME_THRESHOLD = 300_000
30
+
31
+ # rubocop:disable Naming/MemoizedInstanceVariableName
32
+ def initialize hsh = {}
33
+ return unless hsh
34
+
35
+ @enable = hsh[:enable]
36
+ @tags = hsh[:tags]
37
+ @enable_scan_response = hsh[:enable_scan_response]
38
+ @enable_dynamic_sources = hsh[:enable_dynamic_sources]
39
+ @enable_original_object = hsh[:enable_original_object]
40
+ @sampling = Contrast::Components::Sampling::Interface.new(hsh[:sampling])
41
+ @rules = Contrast::Components::AssessRules::Interface.new(hsh[:rules])
42
+ @stacktraces = hsh[:stacktraces]
43
+ @max_context_source_events = hsh[:max_context_source_events]
44
+ @max_propagation_events = hsh[:max_propagation_events]
45
+ @max_rule_reported = hsh[:max_rule_reported]
46
+ @time_limit_threshold = hsh[:time_limit_threshold]
47
+ end
48
+
49
+ # @return [Boolean, true]
50
+ def enable_scan_response
51
+ @enable_scan_response.nil? ? true : @enable_scan_response
52
+ end
53
+
54
+ # @return [Boolean, true]
55
+ def enable_dynamic_sources
56
+ @enable_dynamic_sources.nil? ? true : @enable_dynamic_sources
57
+ end
58
+
59
+ # @return [Boolean, true]
60
+ def enable_original_object
61
+ @enable_original_object.nil? ? true : @enable_original_object
62
+ end
63
+
64
+ # @return [Contrast::Components::Sampling::Interface]
65
+ def sampling
66
+ @sampling ||= Contrast::Components::Sampling::Interface.new
67
+ end
68
+
69
+ # @return [Contrast::Components::AssessRules::Interface]
70
+ def rules
71
+ @rules ||= Contrast::Components::AssessRules::Interface.new
72
+ end
73
+
74
+ def stacktraces
75
+ @stacktraces ||= DEFAULT_STACKTRACES
76
+ end
77
+
78
+ def max_rule_reported
79
+ @max_rule_reported ||= DEFAULT_MAX_RULE_REPORTED
80
+ end
81
+
82
+ def time_limit_threshold
83
+ @time_limit_threshold ||= DEFAULT_MAX_RULE_TIME_THRESHOLD
84
+ end
85
+
86
+ def max_propagation_events
87
+ @max_propagation_events ||= DEFAULT_MAX_PROPAGATION_EVENTS
88
+ end
89
+
90
+ def max_context_source_events
91
+ @max_context_source_events ||= DEFAULT_MAX_SOURCE_EVENTS
92
+ end
93
+
18
94
  def enabled?
19
95
  # config overrides if forcibly set
20
96
  return false if forcibly_disabled?
@@ -28,7 +104,8 @@ module Contrast
28
104
  end
29
105
 
30
106
  def forcibly_disabled?
31
- @_forcibly_disabled = false?(::Contrast::CONFIG.root.assess.enable) if @_forcibly_disabled.nil?
107
+ @_forcibly_disabled = false?(enable) if @_forcibly_disabled.nil?
108
+
32
109
  @_forcibly_disabled
33
110
  end
34
111
 
@@ -40,9 +117,9 @@ module Contrast
40
117
  # faster comparisons when we use it. Anything not one of the known values of
41
118
  # 'NONE', 'SOME', or 'ALL' is treated as 'ALL'
42
119
  #
43
- # @return [Symbol] the normalized value of ::Contrast::CONFIG.root.assess.stacktraces
120
+ # @return [Symbol] the normalized value of ::Contrast::CONFIG.assess.stacktraces
44
121
  def capture_stacktrace_value
45
- @_capture_stacktrace_value ||= case ::Contrast::CONFIG.root.assess.stacktraces.upcase
122
+ @_capture_stacktrace_value ||= case stacktraces&.upcase
46
123
  when 'NONE'
47
124
  :NONE
48
125
  when 'SOME'
@@ -53,7 +130,7 @@ module Contrast
53
130
  end
54
131
 
55
132
  # Consider capture_stacktrace_value along with the node type
56
- # to dertmine whether stacktraces should be captured.
133
+ # to determine whether stacktraces should be captured.
57
134
  #
58
135
  # capture_stacktrace_value -> (:ALL, :NONE, :SOME)
59
136
  # node types (SourceNode, PolicyNode, TriggerNode, PropagationNode)
@@ -72,42 +149,34 @@ module Contrast
72
149
  end
73
150
 
74
151
  def scan_response?
75
- @_scan_response = !false?(::Contrast::CONFIG.root.assess.enable_scan_response) if @_scan_response.nil?
152
+ @_scan_response = !false?(enable_scan_response) if @_scan_response.nil?
153
+
76
154
  @_scan_response
77
155
  end
78
156
 
79
157
  def require_scan?
80
- @_require_scan = !false?(::Contrast::CONFIG.root.agent.ruby.require_scan) if @_require_scan.nil?
158
+ @_require_scan = !false?(::Contrast::CONFIG.agent.ruby.require_scan) if @_require_scan.nil?
81
159
  @_require_scan
82
160
  end
83
161
 
84
162
  def require_dynamic_sources?
85
163
  return @_require_dynamic_sources unless @_require_dynamic_sources.nil?
86
164
 
87
- @_require_dynamic_sources = !false?(::Contrast::CONFIG.root.assess.enable_dynamic_sources)
165
+ @_require_dynamic_sources = !false?(enable_dynamic_sources)
88
166
  end
89
167
 
90
168
  def non_request_tracking?
91
- @_non_request_tracking = true?(::Contrast::CONFIG.root.agent.ruby.non_request_tracking) if
169
+ @_non_request_tracking = true?(::Contrast::CONFIG.agent.ruby.non_request_tracking) if
92
170
  @_non_request_tracking.nil?
93
171
  @_non_request_tracking
94
172
  end
95
173
 
96
- def tags
97
- ::Contrast::CONFIG.root.assess&.tags
98
- end
99
-
100
174
  def disabled_rules
101
- # TODO: RUBY-903
102
- ::Contrast::CONFIG.root.assess&.rules&.disabled_rules ||
103
- ::Contrast::SETTINGS.assess_state.disabled_assess_rules ||
104
- []
175
+ rules&.disabled_rules || ::Contrast::SETTINGS.assess_state.disabled_assess_rules || []
105
176
  end
106
177
 
107
178
  def track_original_object?
108
- if @_track_original_object.nil?
109
- @_track_original_object = !false?(::Contrast::CONFIG.root.assess.enable_original_object)
110
- end
179
+ @_track_original_object = !false?(enable_original_object) if @_track_original_object.nil?
111
180
 
112
181
  @_track_original_object
113
182
  end
@@ -118,26 +187,11 @@ module Contrast
118
187
  ::Contrast::SETTINGS.assess_state.session_id
119
188
  end
120
189
 
121
- def max_source_events
122
- ::Contrast::CONFIG.root.assess.max_context_source_events
123
- end
124
-
125
- def max_propagation_events
126
- ::Contrast::CONFIG.root.assess.max_propagation_events
127
- end
128
-
129
- def time_limit_threshold
130
- ::Contrast::CONFIG.root.assess.time_limit_threshold
131
- end
132
-
133
- def max_rule_reported
134
- ::Contrast::CONFIG.root.assess.max_rule_reported
135
- end
136
-
190
+ # rubocop:enable Naming/MemoizedInstanceVariableName
137
191
  private
138
192
 
139
193
  def forcibly_enabled?
140
- @_forcibly_enabled = true?(::Contrast::CONFIG.root.assess.enable) if @_forcibly_enabled.nil?
194
+ @_forcibly_enabled = true?(::Contrast::CONFIG.assess.enable) if @_forcibly_enabled.nil?
141
195
  @_forcibly_enabled
142
196
  end
143
197
  end
@@ -0,0 +1,36 @@
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/config/base_configuration'
5
+
6
+ module Contrast
7
+ module Components
8
+ # Common Configuration settings. Those in this section pertain to the
9
+ # disabled assess rule functionality of the Agent.
10
+ module AssessRules
11
+ class Interface # :nodoc:
12
+ include Contrast::Config::BaseConfiguration
13
+
14
+ SPEC_KEY = :disabled_rules.cs__freeze
15
+ # @return [Array, nil] list of disabled assess rules
16
+ attr_accessor :disabled_rules
17
+
18
+ def initialize hsh = {}
19
+ return unless hsh
20
+
21
+ @disabled_rules = cast_disabled_rules(hsh)
22
+ end
23
+
24
+ private
25
+
26
+ def cast_disabled_rules hsh
27
+ return unless hsh
28
+ return unless hsh.key?(SPEC_KEY)
29
+ return hsh[SPEC_KEY] if hsh[SPEC_KEY].cs__is_a?(Array)
30
+
31
+ hsh[SPEC_KEY].split(',').map(&:strip) if hsh[SPEC_KEY].cs__is_a?(String)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -34,6 +34,9 @@ module Contrast
34
34
  API_KEY = "Invalid configuration. Missing a required connection value 'api_key' is not set."
35
35
  API_SERVICE_KEY = "Invalid configuration. Missing a required connection value 'service_tag' is not set."
36
36
  API_USERNAME = "Invalid configuration. Missing a required connection value 'user_name' is not set."
37
+
38
+ attr_reader :config
39
+
37
40
  def initialize
38
41
  build
39
42
  end
@@ -62,9 +65,44 @@ module Contrast
62
65
  end
63
66
  alias_method :rebuild, :build
64
67
 
65
- # @return [Contrast::Config::RootConfiguration]
66
- def root
67
- @config.root
68
+ # @return [Contrast::Components::Api::Interface]
69
+ def api
70
+ @config.api
71
+ end
72
+
73
+ # @return [Contrast::Components::Agent::Interface]
74
+ def agent
75
+ @config.agent
76
+ end
77
+
78
+ # @return [Contrast::Components::AppContext::Interface]
79
+ def application
80
+ @config.application
81
+ end
82
+
83
+ # @return [Contrast::Config::ServerConfiguration]
84
+ def server
85
+ @config.server
86
+ end
87
+
88
+ # @return [Contrast::Components::Assess::Interface]
89
+ def assess
90
+ @config.assess
91
+ end
92
+
93
+ # @return [Contrast::Components::Inventory::Interface]
94
+ def inventory
95
+ @config.inventory
96
+ end
97
+
98
+ # @return [Contrast::Components::Protect::Interface]
99
+ def protect
100
+ @config.protect
101
+ end
102
+
103
+ # @return [Contrast::Components::Service::Interface]
104
+ def service
105
+ @config.service
68
106
  end
69
107
 
70
108
  def valid?
@@ -72,6 +110,10 @@ module Contrast
72
110
  @_valid
73
111
  end
74
112
 
113
+ def enable
114
+ @config.enable
115
+ end
116
+
75
117
  def invalid?
76
118
  !valid?
77
119
  end
@@ -85,12 +127,12 @@ module Contrast
85
127
  #
86
128
  # @return [String,nil] the value of the session id set in the configuration, or nil if unset
87
129
  def session_id
88
- root.application.session_id
130
+ application.session_id
89
131
  end
90
132
 
91
133
  # @return [String,nil] the value of the session metadata set in the configuration, or nil if unset
92
134
  def session_metadata
93
- root.application.session_metadata
135
+ application.session_metadata
94
136
  end
95
137
 
96
138
  private
@@ -138,7 +180,7 @@ module Contrast
138
180
  next unless env_key.to_s.start_with?(CONTRAST_ENV_MARKER)
139
181
 
140
182
  config_item = Contrast::Utils::EnvConfigurationItem.new(env_key, env_value)
141
- assign_value_to_path_array(root, config_item.dot_path_array, config_item.value)
183
+ assign_value_to_path_array(self, config_item.dot_path_array, config_item.value)
142
184
  end
143
185
  end
144
186
 
@@ -148,7 +190,7 @@ module Contrast
148
190
  #
149
191
  # @return [String, nil]
150
192
  def api_url
151
- root.api.url
193
+ api.url
152
194
  end
153
195
 
154
196
  # Typically, the following values would be accessed through Contrast::Components::AppContext
@@ -157,7 +199,7 @@ module Contrast
157
199
  #
158
200
  # @return [String, nil]
159
201
  def api_key
160
- root.api.api_key
202
+ api.api_key
161
203
  end
162
204
 
163
205
  # Typically, the following values would be accessed through Contrast::Components::AppContext
@@ -166,7 +208,7 @@ module Contrast
166
208
  #
167
209
  # @return [String, nil]
168
210
  def api_service_key
169
- root.api.service_key
211
+ api.service_key
170
212
  end
171
213
 
172
214
  # Typically, the following values would be accessed through Contrast::Components::AppContext
@@ -175,7 +217,7 @@ module Contrast
175
217
  #
176
218
  # @return [String, nil]
177
219
  def api_username
178
- root.api.user_name
220
+ api.user_name
179
221
  end
180
222
 
181
223
  # Typically, the following values would be accessed through Contrast::Components::AppContext
@@ -184,7 +226,7 @@ module Contrast
184
226
  #
185
227
  # @return [String, nil]
186
228
  def bypass
187
- root.agent.service.bypass
229
+ agent.service.bypass
188
230
  end
189
231
 
190
232
  # Typically, the following values would be accessed through Contrast::Components::AppContext
@@ -193,7 +235,7 @@ module Contrast
193
235
  #
194
236
  # @return [String, nil]
195
237
  def logger_path
196
- root.agent.logger.path
238
+ agent.logger.path
197
239
  end
198
240
 
199
241
  # Assign the value from an ENV variable to the Contrast::Config::RootConfiguration object, when
@@ -29,7 +29,7 @@ module Contrast
29
29
 
30
30
  # Requirement says "must be true" but that
31
31
  # should be "must not be false" -- oops.
32
- @_use_bundled_service ||= !false?(::Contrast::CONFIG.root.agent.start_bundled_service?) &&
32
+ @_use_bundled_service ||= !false?(::Contrast::CONFIG.agent.start_bundled_service?) &&
33
33
  # Either a valid host or a valid socket
34
34
  # Path validity is the service's problem
35
35
  (LOCALHOST.match?(host) || !!socket_path)
@@ -38,7 +38,7 @@ module Contrast
38
38
  def use_agent_communication?
39
39
  return @_use_agent_communication unless @_use_agent_communication.nil?
40
40
 
41
- @_use_agent_communication = true?(::Contrast::CONFIG.root.agent.service.bypass)
41
+ @_use_agent_communication = true?(::Contrast::CONFIG.agent.service.bypass)
42
42
  end
43
43
 
44
44
  # If we're using the agent directly and not using protect, then there is no need to start the service. Because
@@ -52,16 +52,16 @@ module Contrast
52
52
 
53
53
  def host
54
54
  @_host ||=
55
- (::Contrast::CONFIG.root.agent.service.host || Contrast::Config::ServiceConfiguration::DEFAULT_HOST).to_s
55
+ (::Contrast::CONFIG.agent.service.host || Contrast::Components::Service::Interface::DEFAULT_HOST).to_s
56
56
  end
57
57
 
58
58
  def port
59
59
  @_port ||=
60
- (::Contrast::CONFIG.root.agent.service.port || Contrast::Config::ServiceConfiguration::DEFAULT_PORT).to_i
60
+ (::Contrast::CONFIG.agent.service.port || Contrast::Components::Service::Interface::DEFAULT_PORT).to_i
61
61
  end
62
62
 
63
63
  def socket_path
64
- @_socket_path ||= ::Contrast::CONFIG.root.agent.service.socket
64
+ @_socket_path ||= ::Contrast::CONFIG.agent.service.socket
65
65
  end
66
66
 
67
67
  def use_tcp?
@@ -69,17 +69,17 @@ module Contrast
69
69
  end
70
70
 
71
71
  def logger_path
72
- @_logger_path ||= ::Contrast::CONFIG.root.agent.service.logger.path || DEFAULT_SERVICE_LOG
72
+ @_logger_path ||= ::Contrast::CONFIG.agent.service.logger.path || DEFAULT_SERVICE_LOG
73
73
  end
74
74
 
75
75
  def logger_level
76
- @_logger_level ||= ::Contrast::CONFIG.root.agent.service.logger.level || DEFAULT_SERVICE_LEVEL
76
+ @_logger_level ||= ::Contrast::CONFIG.agent.service.logger.level || DEFAULT_SERVICE_LEVEL
77
77
  end
78
78
 
79
79
  private
80
80
 
81
81
  def disabled?
82
- @_disabled = false?(::Contrast::CONFIG.root.agent.start_bundled_service) if @_disabled.nil?
82
+ @_disabled = false?(::Contrast::CONFIG.agent.start_bundled_service) if @_disabled.nil?
83
83
  @_disabled
84
84
  end
85
85
  end
@@ -71,7 +71,7 @@ module Contrast
71
71
 
72
72
  def heap_dump_control
73
73
  @_heap_dump_control ||= begin
74
- config = ::Contrast::CONFIG.root&.agent&.heap_dump
74
+ config = ::Contrast::CONFIG&.agent&.heap_dump
75
75
  {
76
76
  enabled: true?(config&.enable),
77
77
  path: File.absolute_path(config&.path),
@@ -31,7 +31,7 @@ module Contrast
31
31
  end
32
32
 
33
33
  # Name is kept the same - rules to correspond to config,
34
- # mapping. - root.protect.rules
34
+ # mapping. - protect.rules
35
35
  #
36
36
  # @return [Contrast::Config::ProtectRulesConfiguration]
37
37
  def rules
@@ -55,7 +55,7 @@ module Contrast
55
55
  end
56
56
 
57
57
  def rule_config
58
- ::Contrast::CONFIG.root.protect.rules
58
+ ::Contrast::CONFIG.protect.rules
59
59
  end
60
60
 
61
61
  # Returns Protect array of all initialized
@@ -69,7 +69,7 @@ module Contrast
69
69
 
70
70
  def rule_mode rule_id
71
71
  str = rule_id.tr('-', '_')
72
- ::Contrast::CONFIG.root.protect.rules[str]&.applicable_mode ||
72
+ ::Contrast::CONFIG.protect.rules[str]&.applicable_mode ||
73
73
  ::Contrast::SETTINGS.application_state.modes_by_id[rule_id] ||
74
74
  Contrast::Api::Settings::ProtectionRule::Mode::NO_ACTION
75
75
  end
@@ -98,7 +98,7 @@ module Contrast
98
98
  def forcibly_disabled?
99
99
  return @_forcibly_disabled unless @_forcibly_disabled.nil?
100
100
 
101
- @_forcibly_disabled = false?(::Contrast::CONFIG.root.protect.enable)
101
+ @_forcibly_disabled = false?(::Contrast::CONFIG.protect.enable)
102
102
  end
103
103
 
104
104
  private
@@ -106,7 +106,7 @@ module Contrast
106
106
  def forcibly_enabled?
107
107
  return @_forcibly_enabled unless @_forcibly_enabled.nil?
108
108
 
109
- @_forcibly_enabled ||= true?(::Contrast::CONFIG.root.protect.enable)
109
+ @_forcibly_enabled ||= true?(::Contrast::CONFIG.protect.enable)
110
110
  end
111
111
  end
112
112
  end