contrast-agent 6.4.0 → 6.6.0

Sign up to get free protection for your applications and to get access to all the features.
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