contrast-agent 6.4.0 → 6.6.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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/ext/cs__contrast_patch/cs__contrast_patch.c +14 -1
  3. data/lib/contrast/agent/assess/finalizers/hash.rb +1 -0
  4. data/lib/contrast/agent/assess/policy/propagation_method.rb +5 -1
  5. data/lib/contrast/agent/assess/policy/propagator/custom.rb +4 -0
  6. data/lib/contrast/agent/assess/policy/propagator/database_write.rb +5 -0
  7. data/lib/contrast/agent/assess/policy/propagator/split.rb +3 -0
  8. data/lib/contrast/agent/assess/policy/source_method.rb +5 -0
  9. data/lib/contrast/agent/assess/policy/trigger_method.rb +8 -2
  10. data/lib/contrast/agent/assess/tracker.rb +12 -0
  11. data/lib/contrast/agent/inventory/database_config.rb +2 -1
  12. data/lib/contrast/agent/inventory/dependency_analysis.rb +2 -2
  13. data/lib/contrast/agent/inventory/dependency_usage_analysis.rb +1 -1
  14. data/lib/contrast/agent/inventory/policy/datastores.rb +1 -1
  15. data/lib/contrast/agent/inventory/policy/policy.rb +1 -1
  16. data/lib/contrast/agent/patching/policy/method_policy.rb +3 -3
  17. data/lib/contrast/agent/protect/rule/base.rb +1 -1
  18. data/lib/contrast/agent/reporting/reporter_heartbeat.rb +1 -3
  19. data/lib/contrast/agent/reporting/reporting_events/application_defend_activity.rb +17 -21
  20. data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample.rb +1 -1
  21. data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample_activity.rb +26 -3
  22. data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +5 -5
  23. data/lib/contrast/agent/reporting/reporting_utilities/headers.rb +1 -1
  24. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +1 -1
  25. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +1 -1
  26. data/lib/contrast/agent/request_context.rb +8 -0
  27. data/lib/contrast/agent/service_heartbeat.rb +2 -3
  28. data/lib/contrast/agent/static_analysis.rb +1 -1
  29. data/lib/contrast/agent/version.rb +1 -1
  30. data/lib/contrast/agent/worker_thread.rb +10 -0
  31. data/lib/contrast/api/communication/response_processor.rb +1 -1
  32. data/lib/contrast/components/agent.rb +52 -14
  33. data/lib/contrast/components/api.rb +60 -23
  34. data/lib/contrast/components/assess.rb +16 -0
  35. data/lib/contrast/components/contrast_service.rb +1 -1
  36. data/lib/contrast/components/heap_dump.rb +51 -1
  37. data/lib/contrast/components/inventory.rb +19 -13
  38. data/lib/contrast/components/logger.rb +18 -0
  39. data/lib/contrast/components/protect.rb +41 -1
  40. data/lib/contrast/components/sampling.rb +29 -0
  41. data/lib/contrast/config/assess_configuration.rb +33 -3
  42. data/lib/contrast/config/base_configuration.rb +8 -2
  43. data/lib/contrast/config/root_configuration.rb +19 -16
  44. data/lib/contrast/config/service_configuration.rb +4 -4
  45. data/lib/contrast/config.rb +0 -9
  46. data/lib/contrast/extension/object.rb +19 -0
  47. data/lib/contrast/framework/rails/support.rb +7 -3
  48. data/lib/contrast/logger/log.rb +2 -1
  49. data/lib/contrast/utils/assess/event_limit_utils.rb +96 -0
  50. data/lib/contrast/utils/assess/propagation_method_utils.rb +27 -7
  51. data/lib/contrast/utils/log_utils.rb +2 -2
  52. data/lib/contrast/utils/net_http_base.rb +2 -2
  53. data/lib/contrast/utils/patching/policy/patch_utils.rb +1 -1
  54. data/lib/contrast.rb +6 -21
  55. data/resources/assess/policy.json +15 -12
  56. data/resources/deadzone/policy.json +139 -19
  57. data/ruby-agent.gemspec +2 -0
  58. data/service_executables/VERSION +1 -1
  59. data/service_executables/linux/contrast-service +0 -0
  60. data/service_executables/mac/contrast-service +0 -0
  61. metadata +43 -20
  62. data/lib/contrast/config/agent_configuration.rb +0 -63
  63. data/lib/contrast/config/api_configuration.rb +0 -56
  64. data/lib/contrast/config/heap_dump_configuration.rb +0 -59
  65. data/lib/contrast/config/inventory_configuration.rb +0 -33
  66. data/lib/contrast/config/logger_configuration.rb +0 -26
  67. data/lib/contrast/config/protect_configuration.rb +0 -33
  68. data/lib/contrast/config/sampling_configuration.rb +0 -35
@@ -1,10 +1,14 @@
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/components/logger'
5
+
4
6
  module Contrast
5
7
  module Agent
6
8
  # Base class for threads that do async processing
7
9
  class WorkerThread
10
+ include Contrast::Components::Logger::InstanceMethods
11
+
8
12
  def initialize
9
13
  @_thread = nil
10
14
  end
@@ -27,6 +31,12 @@ module Contrast
27
31
  def attempt_to_start?
28
32
  true
29
33
  end
34
+
35
+ def clean_properties
36
+ logger.debug("Cleaning PROPERTIES_HASH size: #{ Contrast::Agent::Assess::Tracker::PROPERTIES_HASH.size }")
37
+ Contrast::Agent::Assess::Tracker.cleanup!
38
+ logger.debug("Cleaned PROPERTIES_HASH size: #{ Contrast::Agent::Assess::Tracker::PROPERTIES_HASH.size }")
39
+ end
30
40
  end
31
41
  end
32
42
  end
@@ -80,7 +80,7 @@ module Contrast
80
80
 
81
81
  logger.info('Current rule settings:')
82
82
 
83
- ::Contrast::PROTECT.rules.each { |k, v| logger.info('Protect Rule mode set', rule: k, mode: v.mode) }
83
+ ::Contrast::PROTECT.defend_rules.each { |k, v| logger.info('Protect Rule mode set', rule: k, mode: v.mode) }
84
84
  logger.info('Disabled Assess Rules', rules: ::Contrast::ASSESS.disabled_rules)
85
85
  end
86
86
  end
@@ -3,6 +3,8 @@
3
3
 
4
4
  require 'rubygems/version'
5
5
  require 'contrast/agent/rule_set'
6
+ require 'contrast/components/logger'
7
+ require 'contrast/components/heap_dump'
6
8
 
7
9
  module Contrast
8
10
  module Components
@@ -13,9 +15,50 @@ module Contrast
13
15
  class Interface
14
16
  include Contrast::Components::ComponentBase
15
17
 
18
+ def initialize hsh = {}
19
+ return unless hsh
20
+
21
+ @_enable = hsh[:enable]
22
+ @_start_bundled_service = hsh[:start_bundled_service]
23
+ @_omit_body = hsh[:omit_body]
24
+ @_service = Contrast::Config::ServiceConfiguration.new(hsh[:service])
25
+ @_logger = Contrast::Components::Logger::Interface.new(hsh[:logger])
26
+ @_ruby = Contrast::Config::RubyConfiguration.new(hsh[:ruby])
27
+ @_heap_dump = Contrast::Components::HeapDump::Interface.new(hsh[:heap_dump])
28
+ end
29
+
30
+ # @return [Boolean, true]
31
+ def start_bundled_service?
32
+ @_start_bundled_service.nil? ? true : @_start_bundled_service
33
+ end
34
+
35
+ def service
36
+ return @_service unless @_service.nil?
37
+
38
+ @_service = Contrast::Config::ServiceConfiguration.new
39
+ end
40
+
41
+ def logger
42
+ return @_logger unless @_logger.nil?
43
+
44
+ @_logger = Contrast::Components::Logger::Interface.new
45
+ end
46
+
47
+ def ruby
48
+ return @_ruby unless @_ruby.nil?
49
+
50
+ @_ruby = Contrast::Config::RubyConfiguration.new
51
+ end
52
+
53
+ def heap_dump
54
+ return @_heap_dump unless @_heap_dump.nil?
55
+
56
+ @_heap_dump = Contrast::Components::HeapDump::Interface.new
57
+ end
58
+
16
59
  def enabled?
17
- @_enabled = !false?(::Contrast::CONFIG.root.enable) if @_enabled.nil?
18
- @_enabled
60
+ @_enable = !false?(::Contrast::CONFIG.root.enable) if @_enable.nil?
61
+ @_enable
19
62
  end
20
63
 
21
64
  def disabled?
@@ -23,11 +66,11 @@ module Contrast
23
66
  end
24
67
 
25
68
  def enable!
26
- @_enabled = true
69
+ @_enable = true
27
70
  end
28
71
 
29
72
  def disable!
30
- @_enabled = false
73
+ @_enable = false
31
74
  Contrast::Agent::TracePointHook.disable
32
75
  Contrast::Agent.thread_watcher&.shutdown!
33
76
  end
@@ -41,8 +84,7 @@ module Contrast
41
84
  end
42
85
 
43
86
  def patch_yield?
44
- @_patch_yield = !false?(::Contrast::CONFIG.root.agent.ruby.propagate_yield) if @_patch_yield.nil?
45
- @_patch_yield
87
+ !false?(ruby.propagate_yield)
46
88
  end
47
89
 
48
90
  def interpolation_enabled?
@@ -52,18 +94,14 @@ module Contrast
52
94
  end
53
95
 
54
96
  def omit_body?
55
- @_omit_body = true?(::Contrast::CONFIG.root.agent.omit_body) if @_omit_body.nil?
56
97
  @_omit_body
57
98
  end
58
99
 
59
100
  def exception_control
60
101
  @_exception_control ||= {
61
- enable: true?(::Contrast::CONFIG.root.agent.ruby.exceptions.capture),
62
- status:
63
- ::Contrast::CONFIG.root.agent.ruby.exceptions.override_status || 403,
64
- message:
65
- ::Contrast::CONFIG.root.agent.ruby.exceptions.override_message ||
66
- Contrast::Utils::ObjectShare::OVERRIDE_MESSAGE
102
+ enable: true?(ruby.exceptions.capture),
103
+ status: ruby.exceptions.override_status || 403,
104
+ message: ruby.exceptions.override_message || Contrast::Utils::ObjectShare::OVERRIDE_MESSAGE
67
105
  }
68
106
  end
69
107
 
@@ -87,7 +125,7 @@ module Contrast
87
125
  def retrieve_protect_ruleset
88
126
  return {} unless enabled? && ::Contrast::PROTECT.enabled?
89
127
 
90
- ::Contrast::PROTECT.rules
128
+ ::Contrast::PROTECT.defend_rules
91
129
  end
92
130
  end
93
131
  end
@@ -3,6 +3,9 @@
3
3
 
4
4
  require 'contrast/components/base'
5
5
  require 'contrast/components/config'
6
+ require 'contrast/config/api_proxy_configuration'
7
+ require 'contrast/config/request_audit_configuration'
8
+ require 'contrast/config/certification_configuration'
6
9
 
7
10
  module Contrast
8
11
  module Components
@@ -12,50 +15,86 @@ module Contrast
12
15
  # parent_configuration_spec.yaml.
13
16
  class Interface
14
17
  include Contrast::Components::ComponentBase
18
+ include Contrast::Config::BaseConfiguration
19
+
20
+ # @return [String]
21
+ attr_accessor :api_key
22
+ # @return [String]
23
+ attr_accessor :user_name
24
+ # @return [String]
25
+ attr_accessor :service_key
26
+ attr_writer :url
27
+
28
+ DEFAULT_URL = 'https://app.contrastsecurity.com/Contrast'
29
+
30
+ def initialize hsh = {}
31
+ return unless hsh
32
+
33
+ @api_key = hsh[:api_key]
34
+ @url = hsh[:url]
35
+ @user_name = hsh[:user_name]
36
+ @service_key = hsh[:service_key]
37
+ @_proxy = Contrast::Config::ApiProxyConfiguration.new(hsh[:proxy])
38
+ @_request_audit = Contrast::Config::RequestAuditConfiguration.new(hsh[:request_audit])
39
+ @_certificate = Contrast::Config::CertificationConfiguration.new(hsh[:certificate])
40
+ end
15
41
 
16
- def api_url
17
- @_api_url ||= begin
18
- tmp = ::Contrast::CONFIG.root.api.url
19
- tmp += '/Contrast' unless tmp.end_with?('/Contrast')
20
- tmp
21
- end
42
+ def url
43
+ @url.nil? ? DEFAULT_URL : @url
22
44
  end
23
45
 
24
- def api_key
25
- @_api_key ||= ::Contrast::CONFIG.root.api.api_key
46
+ # @return [Contrast::Config::ApiProxyConfiguration]
47
+ def proxy
48
+ return @_proxy unless @_proxy.nil?
49
+
50
+ @_proxy = Contrast::Config::ApiProxyConfiguration.new
26
51
  end
27
52
 
28
- def service_key
29
- @_service_key ||= ::Contrast::CONFIG.root.api.service_key
53
+ # @return [Contrast::Config::RequestAuditConfiguration]
54
+ def request_audit
55
+ return @_request_audit unless @_request_audit.nil?
56
+
57
+ @_request_audit = Contrast::Config::RequestAuditConfiguration.new
30
58
  end
31
59
 
32
- def username
33
- @_username ||= ::Contrast::CONFIG.root.api.user_name
60
+ # @return [Contrast::Config::CertificationConfiguration]
61
+ def certificate
62
+ return @_certificate unless @_certificate.nil?
63
+
64
+ @_certificate = Contrast::Config::CertificationConfiguration.new
34
65
  end
35
66
 
36
- def proxy_enabled?
37
- return @_proxy_enabled unless @_proxy_enabled.nil?
67
+ def api_url
68
+ @_api_url ||= begin
69
+ tmp = Contrast::CONFIG.root.api.url
70
+ tmp += '/Contrast' unless tmp.end_with?('/Contrast')
71
+ tmp
72
+ end
73
+ end
38
74
 
39
- @_proxy_enabled = true?(::Contrast::CONFIG.root.api.proxy.enable)
75
+ def proxy_enable
76
+ return @_proxy_enable unless @_proxy_enable.nil?
77
+
78
+ @_proxy_enable = true?(::Contrast::CONFIG.root.api.proxy.enable)
40
79
  end
41
80
 
42
81
  def proxy_url
43
- @_proxy_url ||= ::Contrast::CONFIG.root.api.proxy.url
82
+ proxy.url
44
83
  end
45
84
 
46
- def request_audit_enable?
85
+ def request_audit_enable
47
86
  return @_request_audit_enable unless @_request_audit_enable.nil?
48
87
 
49
88
  @_request_audit_enable = true?(::Contrast::CONFIG.root.api.request_audit.enable)
50
89
  end
51
90
 
52
- def request_audit_requests?
91
+ def request_audit_requests
53
92
  return @_request_audit_requests unless @_request_audit_requests.nil?
54
93
 
55
94
  @_request_audit_requests = true?(::Contrast::CONFIG.root.api.request_audit.requests)
56
95
  end
57
96
 
58
- def request_audit_responses?
97
+ def request_audit_responses
59
98
  return @_request_audit_responses unless @_request_audit_responses.nil?
60
99
 
61
100
  @_request_audit_responses = true?(::Contrast::CONFIG.root.api.request_audit.responses)
@@ -65,10 +104,8 @@ module Contrast
65
104
  @_request_audit_path ||= ::Contrast::CONFIG.root.api.request_audit.path.to_s
66
105
  end
67
106
 
68
- def certification_enabled?
69
- return @_certification_enabled unless @_certification_enabled.nil?
70
-
71
- @_certification_enabled = certification_truly_enabled?(::Contrast::CONFIG.root.api.certificate)
107
+ def certification_enable
108
+ @_certification_enable ||= certification_truly_enabled?(::Contrast::CONFIG.root.api.certificate)
72
109
  end
73
110
 
74
111
  def certification_ca_file
@@ -118,6 +118,22 @@ module Contrast
118
118
  ::Contrast::SETTINGS.assess_state.session_id
119
119
  end
120
120
 
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
+
121
137
  private
122
138
 
123
139
  def forcibly_enabled?
@@ -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.root.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)
@@ -2,11 +2,61 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'contrast/components/base'
5
- require 'contrast/components/heap_dump'
5
+ require 'contrast/config/base_configuration'
6
6
 
7
7
  module Contrast
8
8
  module Components
9
9
  module HeapDump
10
+ # Interface used to build the HeapDump settings and component.
11
+ class Interface
12
+ include Contrast::Config::BaseConfiguration
13
+
14
+ DEFAULT_PATH = 'contrast_heap_dumps' # saved
15
+ DEFAULT_MS = 10_000
16
+ DEFAULT_COUNT = 5
17
+
18
+ def initialize hsh = {}
19
+ return unless hsh
20
+
21
+ @_enable = hsh[:enable]
22
+ @_path = hsh[:path]
23
+ @_delay_ms = hsh[:delay_ms]
24
+ @_window_ms = hsh[:window_ms]
25
+ @_count = hsh[:count]
26
+ @_clean = hsh[:clean]
27
+ end
28
+
29
+ # @return [Boolean, String] should dumps be taken
30
+ def enable
31
+ @_enable.nil? ? Contrast::Utils::ObjectShare::FALSE : @_enable
32
+ end
33
+
34
+ # @return [String, DEFAULT_PATH] dir to which dumps should be
35
+ def path
36
+ @_path ||= DEFAULT_PATH
37
+ end
38
+
39
+ # @return [Integer, DEFAULT_MS] time, in ms, after initialization
40
+ def delay_ms
41
+ @_delay_ms ||= DEFAULT_MS
42
+ end
43
+
44
+ # @return [Integer, DEFAULT_MS] ms between each dump
45
+ def window_ms
46
+ @_window_ms ||= DEFAULT_MS
47
+ end
48
+
49
+ # @return [Integer, DEFAULT_COUNT] number of dumps to take
50
+ def count
51
+ @_count ||= DEFAULT_COUNT
52
+ end
53
+
54
+ # @return [Boolean, String] remove temporary objects or not
55
+ def clean
56
+ @_clean.nil? ? Contrast::Utils::ObjectShare::FALSE : @_clean
57
+ end
58
+ end
59
+
10
60
  # A wrapper build around the Common Agent Configuration project to allow
11
61
  # for access of the values contained in its
12
62
  # parent_configuration_spec.yaml.
@@ -1,29 +1,35 @@
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/components/base'
5
+
4
6
  module Contrast
5
7
  module Components
6
8
  module Inventory
7
- # A wrapper build around the Common Agent Configuration project to allow
8
- # for access of the values contained in its
9
- # parent_configuration_spec.yaml.
10
- # Specifically, this allows for querying the state of the Inventory
11
- # product.
9
+ # Interface component for Inventory settings used to store the values from
10
+ # settings file and assert state with check methods.
12
11
  class Interface
13
12
  include Contrast::Components::ComponentBase
14
13
 
15
- def enabled?
16
- @_enabled = !false?(::Contrast::CONFIG.root.inventory.enable) if @_enabled.nil?
17
- @_enabled
14
+ # @return [Array, nil] tags
15
+ attr_accessor :tags
16
+
17
+ def initialize hsh = {}
18
+ return unless hsh
19
+
20
+ @enable = !false?(hsh[:enable])
21
+ @analyze_libraries = !false?(hsh[:analyze_libraries])
22
+ @tags = hsh[:tags]
18
23
  end
19
24
 
20
- def analyze_libraries?
21
- @_analyze_libraries = !false?(::Contrast::CONFIG.root.inventory.analyze_libraries) if @_analyze_libraries.nil?
22
- @_analyze_libraries
25
+ # return [Boolean]
26
+ def enable
27
+ @enable.nil? ? true : @enable
23
28
  end
24
29
 
25
- def tags
26
- ::Contrast::CONFIG.root.inventory&.tags
30
+ # return [Boolean]
31
+ def analyze_libraries
32
+ @analyze_libraries.nil? ? true : @analyze_libraries
27
33
  end
28
34
  end
29
35
  end
@@ -28,8 +28,26 @@ module Contrast
28
28
  end
29
29
  end
30
30
 
31
+ # So This class here follows the update for the configuration
32
+ # and from know on ( if it's as we planned it to be) it will hold the
33
+ # instance methods and will initialize new instances for where they're needed
31
34
  class Interface
32
35
  include InstanceMethods
36
+
37
+ # @return [String, nil]
38
+ attr_accessor :path
39
+ # @return [String, nil]
40
+ attr_accessor :level
41
+ # @return [String, nil]
42
+ attr_accessor :progname
43
+
44
+ def initialize hsh = {}
45
+ return unless hsh
46
+
47
+ @path = hsh[:path]
48
+ @level = hsh[:level]
49
+ @progname = hsh[:progname]
50
+ end
33
51
  end
34
52
  end
35
53
  end
@@ -2,6 +2,8 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'contrast/components/base'
5
+ require 'contrast/config/exception_configuration'
6
+ require 'contrast/config/protect_rule_configuration'
5
7
 
6
8
  module Contrast
7
9
  module Components
@@ -10,6 +12,39 @@ module Contrast
10
12
  # its parent_configuration_spec.yaml. Specifically, this allows for querying the state of the Protect product.
11
13
  class Interface
12
14
  include Contrast::Components::ComponentBase
15
+ include Contrast::Config::BaseConfiguration
16
+
17
+ # @return [Boolean, nil]
18
+ attr_accessor :enable
19
+
20
+ def initialize hsh = {}
21
+ return unless hsh
22
+
23
+ @_exceptions = Contrast::Config::ExceptionConfiguration.new(hsh[:exceptions])
24
+ @_rules = Contrast::Config::ProtectRulesConfiguration.new(hsh[:rules])
25
+ @enable = hsh[:enable]
26
+ end
27
+
28
+ # @return [Contrast::Config::ExceptionConfiguration]
29
+ def exceptions
30
+ @_exceptions ||= Contrast::Config::ExceptionConfiguration.new
31
+ end
32
+
33
+ # Name is kept the same - rules to correspond to config,
34
+ # mapping. - root.protect.rules
35
+ #
36
+ # @return [Contrast::Config::ProtectRulesConfiguration]
37
+ def rules
38
+ @_rules ||= Contrast::Config::ProtectRulesConfiguration.new
39
+ end
40
+
41
+ def rules= new_rules
42
+ @_rules = new_rules
43
+ end
44
+
45
+ def exceptions= new_exceptions
46
+ @_exceptions = new_exceptions
47
+ end
13
48
 
14
49
  def enabled?
15
50
  # config overrides if forcibly set
@@ -23,7 +58,12 @@ module Contrast
23
58
  ::Contrast::CONFIG.root.protect.rules
24
59
  end
25
60
 
26
- def rules
61
+ # Returns Protect array of all initialized
62
+ # protect rules.
63
+ #
64
+ # @return defend_rules[Hash<Contrast::SETTINGS.protect_state.rules>]
65
+ #
66
+ def defend_rules
27
67
  ::Contrast::SETTINGS.protect_state.rules
28
68
  end
29
69
 
@@ -91,6 +91,35 @@ module Contrast
91
91
  include Constants
92
92
  include ClassMethods
93
93
  end
94
+
95
+ class Interface # :nodoc:
96
+ include InstanceMethods
97
+ include Contrast::Config::BaseConfiguration
98
+
99
+ # @return [Integer, nil]
100
+ attr_reader :baseline
101
+ # @return [Integer, nil]
102
+ attr_reader :request_frequency
103
+ # @return [Integer, nil]
104
+ attr_reader :response_frequency
105
+ # @return [Integer, nil]
106
+ attr_reader :window_ms
107
+
108
+ def initialize hsh = {}
109
+ return unless hsh
110
+
111
+ @enable = hsh[:enable]
112
+ @baseline = hsh[:baseline]
113
+ @request_frequency = hsh[:request_frequency]
114
+ @response_frequency = hsh[:response_frequency]
115
+ @window_ms = hsh[:window_ms]
116
+ end
117
+
118
+ # @return [Boolean, false]
119
+ def enable
120
+ !!@enable
121
+ end
122
+ end
94
123
  end
95
124
  end
96
125
  end
@@ -1,6 +1,8 @@
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/components/sampling'
5
+
4
6
  module Contrast
5
7
  module Config
6
8
  # Common Configuration settings. Those in this section pertain to the
@@ -15,6 +17,10 @@ module Contrast
15
17
  attr_writer :enable_scan_response, :enable_dynamic_sources, :sampling, :rules, :stacktraces
16
18
 
17
19
  DEFAULT_STACKTRACES = 'ALL'
20
+ DEFAULT_MAX_SOURCE_EVENTS = 50_000
21
+ DEFAULT_MAX_PROPAGATION_EVENTS = 50_000
22
+ DEFAULT_MAX_RULE_REPORTED = 50_000
23
+ DEFAULT_MAX_RULE_TIME_THRESHOLD = 300_000
18
24
 
19
25
  def initialize hsh = {}
20
26
  return unless hsh
@@ -24,9 +30,13 @@ module Contrast
24
30
  @enable_scan_response = hsh[:enable_scan_response]
25
31
  @enable_dynamic_sources = hsh[:enable_dynamic_sources]
26
32
  @enable_original_object = hsh[:enable_original_object]
27
- @sampling = Contrast::Config::SamplingConfiguration.new(hsh[:sampling])
33
+ @sampling = Contrast::Components::Sampling::Interface.new(hsh[:sampling])
28
34
  @rules = Contrast::Config::AssessRulesConfiguration.new(hsh[:rules])
29
35
  @stacktraces = hsh[:stacktraces]
36
+ @max_context_source_events = hsh[:max_context_source_events]
37
+ @max_propagation_events = hsh[:max_propagation_events]
38
+ @max_rule_reported = hsh[:max_rule_reported]
39
+ @time_limit_threshold = hsh[:time_limit_threshold]
30
40
  end
31
41
 
32
42
  # @return [Boolean, true]
@@ -44,9 +54,9 @@ module Contrast
44
54
  @enable_original_object.nil? ? true : @enable_original_object
45
55
  end
46
56
 
47
- # @return [Contrast::Config::SamplingConfiguration]
57
+ # @return [Contrast::Components::Sampling::Interface]
48
58
  def sampling
49
- @sampling ||= Contrast::Config::SamplingConfiguration.new
59
+ @sampling ||= Contrast::Components::Sampling::Interface.new
50
60
  end
51
61
 
52
62
  # @return [Contrast::Config::AssessRulesConfiguration]
@@ -58,6 +68,26 @@ module Contrast
58
68
  def stacktraces
59
69
  @stacktraces ||= DEFAULT_STACKTRACES
60
70
  end
71
+
72
+ # @return [int] max number of context source events in single request
73
+ def max_context_source_events
74
+ @max_context_source_events ||= DEFAULT_MAX_SOURCE_EVENTS
75
+ end
76
+
77
+ # @return [int] max number of propagation events in single request
78
+ def max_propagation_events
79
+ @max_propagation_events ||= DEFAULT_MAX_PROPAGATION_EVENTS
80
+ end
81
+
82
+ # @return [int] max number of rules reported within time_limit_threshold
83
+ def max_rule_reported
84
+ @max_rule_reported ||= DEFAULT_MAX_RULE_REPORTED
85
+ end
86
+
87
+ # @return [int] max ms threshold for reporting rules
88
+ def time_limit_threshold
89
+ @time_limit_threshold ||= DEFAULT_MAX_RULE_TIME_THRESHOLD
90
+ end
61
91
  end
62
92
  end
63
93
  end
@@ -10,12 +10,18 @@ module Contrast
10
10
  # Configuration settings to usable Ruby classes.
11
11
  module BaseConfiguration
12
12
  extend Forwardable
13
+ AT_UNDERSCORE = '@_'
13
14
 
14
15
  def to_hash
15
16
  hsh = {}
16
17
  instance_variables.each do |iv|
17
- # strip the '@' to get the key
18
- key = iv.to_s[1..]
18
+ # strip the '@' of '@_' to get the key
19
+ string_iv = iv.to_s
20
+ key = if string_iv.include?(AT_UNDERSCORE)
21
+ string_iv[2..]
22
+ else
23
+ string_iv[1..]
24
+ end
19
25
  hsh[key] = send(key.to_sym)
20
26
  end
21
27
  hsh