contrast-agent 6.2.0 → 6.3.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 (110) hide show
  1. checksums.yaml +4 -4
  2. data/ext/cs__assess_basic_object/cs__assess_basic_object.c +7 -5
  3. data/ext/cs__assess_kernel/cs__assess_kernel.c +14 -3
  4. data/ext/cs__assess_kernel/cs__assess_kernel.h +2 -0
  5. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +10 -3
  6. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.h +2 -1
  7. data/ext/cs__assess_regexp/cs__assess_regexp.c +9 -7
  8. data/ext/{cs__assess_string_interpolation26/cs__assess_string_interpolation26.c → cs__assess_string_interpolation/cs__assess_string_interpolation.c} +14 -3
  9. data/ext/{cs__assess_string_interpolation26/cs__assess_string_interpolation26.h → cs__assess_string_interpolation/cs__assess_string_interpolation.h} +1 -1
  10. data/ext/{cs__assess_string_interpolation26 → cs__assess_string_interpolation}/extconf.rb +0 -0
  11. data/ext/cs__common/cs__common.c +5 -4
  12. data/ext/cs__contrast_patch/cs__contrast_patch.c +3 -10
  13. data/lib/contrast/agent/assess/events/source_event.rb +16 -12
  14. data/lib/contrast/agent/assess/policy/policy_node.rb +6 -0
  15. data/lib/contrast/agent/assess/policy/propagation_method.rb +3 -39
  16. data/lib/contrast/agent/assess/policy/propagation_node.rb +8 -0
  17. data/lib/contrast/agent/assess/policy/propagator/base.rb +2 -0
  18. data/lib/contrast/agent/assess/policy/source_method.rb +2 -47
  19. data/lib/contrast/agent/assess/policy/source_node.rb +1 -0
  20. data/lib/contrast/agent/assess/policy/trigger_node.rb +8 -0
  21. data/lib/contrast/agent/assess/property/evented.rb +4 -18
  22. data/lib/contrast/agent/assess/tag.rb +19 -0
  23. data/lib/contrast/agent/at_exit_hook.rb +8 -8
  24. data/lib/contrast/agent/inventory/database_config.rb +6 -3
  25. data/lib/contrast/agent/inventory/dependency_analysis.rb +3 -2
  26. data/lib/contrast/agent/inventory/dependency_usage_analysis.rb +10 -10
  27. data/lib/contrast/agent/middleware.rb +4 -0
  28. data/lib/contrast/agent/patching/policy/after_load_patcher.rb +27 -2
  29. data/lib/contrast/agent/patching/policy/policy.rb +5 -0
  30. data/lib/contrast/agent/patching/policy/policy_node.rb +6 -0
  31. data/lib/contrast/agent/patching/policy/trigger_node.rb +3 -0
  32. data/lib/contrast/agent/protect/policy/applies_deserialization_rule.rb +3 -4
  33. data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +1 -0
  34. data/lib/contrast/agent/protect/policy/rule_applicator.rb +2 -2
  35. data/lib/contrast/agent/protect/rule/base.rb +1 -0
  36. data/lib/contrast/agent/protect/rule/no_sqli.rb +2 -0
  37. data/lib/contrast/agent/reporting/reporter.rb +32 -7
  38. data/lib/contrast/agent/reporting/reporter_heartbeat.rb +21 -15
  39. data/lib/contrast/agent/reporting/reporting_events/application_update.rb +5 -24
  40. data/lib/contrast/agent/reporting/reporting_events/architecture_component.rb +8 -1
  41. data/lib/contrast/agent/reporting/reporting_events/discovered_route.rb +8 -1
  42. data/lib/contrast/agent/reporting/reporting_events/finding.rb +7 -1
  43. data/lib/contrast/agent/reporting/reporting_events/finding_event.rb +10 -1
  44. data/lib/contrast/agent/reporting/reporting_events/finding_event_object.rb +11 -1
  45. data/lib/contrast/agent/reporting/reporting_events/finding_event_parent_object.rb +11 -1
  46. data/lib/contrast/agent/reporting/reporting_events/finding_event_property.rb +12 -1
  47. data/lib/contrast/agent/reporting/reporting_events/finding_event_signature.rb +10 -1
  48. data/lib/contrast/agent/reporting/reporting_events/finding_event_source.rb +11 -1
  49. data/lib/contrast/agent/reporting/reporting_events/finding_event_stack.rb +11 -1
  50. data/lib/contrast/agent/reporting/reporting_events/finding_event_taint_range.rb +11 -1
  51. data/lib/contrast/agent/reporting/reporting_events/finding_request.rb +11 -1
  52. data/lib/contrast/agent/reporting/reporting_events/library_discovery.rb +29 -32
  53. data/lib/contrast/agent/reporting/reporting_events/library_usage_observation.rb +13 -1
  54. data/lib/contrast/agent/reporting/reporting_events/observed_library_usage.rb +11 -8
  55. data/lib/contrast/agent/reporting/reporting_events/observed_route.rb +12 -5
  56. data/lib/contrast/agent/reporting/reporting_events/preflight_message.rb +8 -1
  57. data/lib/contrast/agent/reporting/reporting_events/reporting_event.rb +9 -1
  58. data/lib/contrast/agent/reporting/reporting_events/route_discovery.rb +10 -1
  59. data/lib/contrast/agent/reporting/reporting_events/route_discovery_observation.rb +11 -4
  60. data/lib/contrast/agent/reporting/reporting_events/server_activity.rb +0 -8
  61. data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +1 -4
  62. data/lib/contrast/agent/reporting/reporting_utilities/dtm_message.rb +0 -22
  63. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +1 -3
  64. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +1 -11
  65. data/lib/contrast/agent/request.rb +5 -7
  66. data/lib/contrast/agent/request_context.rb +8 -17
  67. data/lib/contrast/agent/request_context_extend.rb +8 -9
  68. data/lib/contrast/agent/request_handler.rb +9 -38
  69. data/lib/contrast/agent/rule_set.rb +4 -0
  70. data/lib/contrast/agent/service_heartbeat.rb +1 -1
  71. data/lib/contrast/agent/static_analysis.rb +6 -11
  72. data/lib/contrast/agent/telemetry/base.rb +35 -35
  73. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_base.rb +2 -0
  74. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_event.rb +2 -0
  75. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_message.rb +5 -2
  76. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_message_exception.rb +3 -0
  77. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_stack_frame.rb +3 -0
  78. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exceptions.rb +0 -1
  79. data/lib/contrast/agent/thread_watcher.rb +1 -4
  80. data/lib/contrast/agent/version.rb +1 -1
  81. data/lib/contrast/api/communication/socket.rb +1 -0
  82. data/lib/contrast/api/decorators/message.rb +0 -6
  83. data/lib/contrast/api/decorators.rb +0 -2
  84. data/lib/contrast/components/assess.rb +0 -6
  85. data/lib/contrast/components/config.rb +18 -2
  86. data/lib/contrast/config/base_configuration.rb +0 -13
  87. data/lib/contrast/config/root_configuration.rb +1 -0
  88. data/lib/contrast/config/ruby_configuration.rb +2 -9
  89. data/lib/contrast/configuration.rb +0 -2
  90. data/lib/contrast/extension/assess/eval_trigger.rb +0 -4
  91. data/lib/contrast/extension/assess/hash.rb +3 -2
  92. data/lib/contrast/extension/assess/kernel.rb +22 -0
  93. data/lib/contrast/extension/assess/marshal.rb +16 -0
  94. data/lib/contrast/extension/assess/string.rb +21 -20
  95. data/lib/contrast/framework/base_support.rb +8 -0
  96. data/lib/contrast/framework/manager.rb +6 -20
  97. data/lib/contrast/framework/manager_extend.rb +0 -1
  98. data/lib/contrast/framework/rails/patch/action_controller_live_buffer.rb +11 -16
  99. data/lib/contrast/logger/aliased_logging.rb +2 -0
  100. data/lib/contrast/utils/assess/source_method_utils.rb +0 -9
  101. data/lib/contrast/utils/lru_cache.rb +3 -0
  102. data/lib/contrast/utils/middleware_utils.rb +2 -0
  103. data/lib/contrast/utils/telemetry_client.rb +7 -7
  104. data/resources/assess/policy.json +2 -11
  105. data/ruby-agent.gemspec +1 -1
  106. metadata +22 -20
  107. data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exceptions_report.rb +0 -30
  108. data/lib/contrast/api/decorators/application_update.rb +0 -44
  109. data/lib/contrast/api/decorators/library.rb +0 -56
  110. data/lib/contrast/framework/platform_version.rb +0 -22
@@ -16,6 +16,8 @@ module Contrast
16
16
  # includes the literal URL and HTTP Verb used to invoke them, as they must have been called at this point to be
17
17
  # recorded.
18
18
  class DiscoveredRoute < Contrast::Agent::Reporting::ObservedRoute
19
+ include Contrast::Components::Logger::InstanceMethods
20
+
19
21
  class << self
20
22
  # @param obj [Regexp, Object]
21
23
  # @return [String]
@@ -104,7 +106,12 @@ module Contrast
104
106
  end
105
107
 
106
108
  def to_controlled_hash
107
- validate
109
+ begin
110
+ validate
111
+ rescue ArgumentError => e
112
+ logger.error('DiscoveredRoute validation failed with: ', e)
113
+ return
114
+ end
108
115
  { session_id: ::Contrast::ASSESS.session_id, signature: @signature, verb: @verb, url: @url }.compact
109
116
  end
110
117
 
@@ -130,7 +130,13 @@ module Contrast
130
130
  # @return [Hash]
131
131
  # @raise [ArgumentError]
132
132
  def to_controlled_hash
133
- validate
133
+ begin
134
+ validate
135
+ rescue ArgumentError => e
136
+ logger.error('Finding event validation failed with: ', e)
137
+ return
138
+ end
139
+
134
140
  hsh = {
135
141
  created: created,
136
142
  hash: hash_code.to_s,
@@ -8,6 +8,7 @@ require 'contrast/agent/reporting/reporting_events/finding_event_signature'
8
8
  require 'contrast/agent/reporting/reporting_events/finding_event_source'
9
9
  require 'contrast/agent/reporting/reporting_events/finding_event_stack'
10
10
  require 'contrast/agent/reporting/reporting_events/finding_event_taint_range'
11
+ require 'contrast/components/logger'
11
12
 
12
13
  module Contrast
13
14
  module Agent
@@ -17,6 +18,8 @@ module Contrast
17
18
  # construct the vulnerability information for the assess feature. They represent the operation the application
18
19
  # underwent that transformed data during the dataflow.
19
20
  class FindingEvent
21
+ include Contrast::Components::Logger::InstanceMethods
22
+
20
23
  # @return [Symbol] what the event did; CREATION, A2O, A2P, A2A, A2R, O2A, O2O, O2P, O2R, P2A, P2O, P2P, P2R,
21
24
  # TAG, TRIGGER.
22
25
  attr_reader :action
@@ -120,7 +123,13 @@ module Contrast
120
123
  # @return [Hash]
121
124
  # @raise [ArgumentError]
122
125
  def to_controlled_hash # rubocop:disable Metrics/AbcSize
123
- validate
126
+ begin
127
+ validate
128
+ rescue ArgumentError => e
129
+ logger.error('FindingEvent validation failed with: ', e)
130
+ return
131
+ end
132
+
124
133
  {
125
134
  action: action,
126
135
  args: args.map(&:to_controlled_hash),
@@ -3,6 +3,7 @@
3
3
 
4
4
  require 'base64'
5
5
  require 'contrast/agent/assess/contrast_object'
6
+ require 'contrast/components/logger'
6
7
 
7
8
  module Contrast
8
9
  module Agent
@@ -12,6 +13,8 @@ module Contrast
12
13
  # TeamServer to construct the vulnerability information for the assess feature. They represent those parts of the
13
14
  # objects that were acted on in a Dataflow Finding.
14
15
  class FindingEventObject
16
+ include Contrast::Components::Logger::InstanceMethods
17
+
15
18
  # @return [Integer] the id of the Object this represents.
16
19
  attr_reader :hash
17
20
  # @return [Boolean] if the Object is tracked or not
@@ -52,7 +55,13 @@ module Contrast
52
55
  # @return [Hash]
53
56
  # @raise [ArgumentError]
54
57
  def to_controlled_hash
55
- validate
58
+ begin
59
+ validate
60
+ rescue ArgumentError => e
61
+ logger.error('FindingEventObject validation failed with: ', e)
62
+ return
63
+ end
64
+
56
65
  {
57
66
  hash: hash,
58
67
  tracked: tracked,
@@ -60,6 +69,7 @@ module Contrast
60
69
  }
61
70
  end
62
71
 
72
+ # @raise [ArgumentError]
63
73
  def validate
64
74
  raise(ArgumentError, "#{ self } did not have a proper hash. Unable to continue.") unless hash
65
75
  raise(ArgumentError, "#{ self } did not have a proper tracked. Unable to continue.") if tracked.nil?
@@ -2,6 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'base64'
5
+ require 'contrast/components/logger'
5
6
 
6
7
  module Contrast
7
8
  module Agent
@@ -11,6 +12,8 @@ module Contrast
11
12
  # used by TeamServer to relate this event to those that came previously. They represent the events that directly
12
13
  # preceding the FindingEvent generated.
13
14
  class FindingEventParentObject
15
+ include Contrast::Components::Logger::InstanceMethods
16
+
14
17
  # @return [Integer] the Id of the parent event
15
18
  attr_reader :id
16
19
 
@@ -24,12 +27,19 @@ module Contrast
24
27
  # @return [Hash]
25
28
  # @raise [ArgumentError]
26
29
  def to_controlled_hash
27
- validate
30
+ begin
31
+ validate
32
+ rescue ArgumentError => e
33
+ logger.error('FindingEventParentObject validation failed with: ', e)
34
+ return
35
+ end
36
+
28
37
  {
29
38
  id: id
30
39
  }
31
40
  end
32
41
 
42
+ # @raise [ArgumentError]
33
43
  def validate
34
44
  raise(ArgumentError, "#{ self } did not have a proper id. Unable to continue.") unless id
35
45
  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/logger'
5
+
4
6
  module Contrast
5
7
  module Agent
6
8
  module Reporting
@@ -8,6 +10,8 @@ module Contrast
8
10
  # system to relay this information in the Finding/Trace messages. Events have properties on them which are held
9
11
  # as an array of key-value pairs.
10
12
  class FindingEventProperty
13
+ include Contrast::Components::Logger::InstanceMethods
14
+
11
15
  # @return [String] the key of the property
12
16
  attr_reader :key
13
17
  # @return [String] the value of the source
@@ -24,13 +28,20 @@ module Contrast
24
28
  # @return [Hash]
25
29
  # @raise [ArgumentError]
26
30
  def to_controlled_hash
27
- validate
31
+ begin
32
+ validate
33
+ rescue ArgumentError => e
34
+ logger.error('FindingEventProperty validation failed with: ', e)
35
+ return
36
+ end
37
+
28
38
  {
29
39
  key: key,
30
40
  value: value
31
41
  }
32
42
  end
33
43
 
44
+ # @raise [ArgumentError]
34
45
  def validate
35
46
  raise(ArgumentError, "#{ self } did not have a proper key. Unable to continue.") unless key && !key.empty?
36
47
  end
@@ -2,6 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'contrast/utils/object_share'
5
+ require 'contrast/components/logger'
5
6
 
6
7
  module Contrast
7
8
  module Agent
@@ -11,6 +12,8 @@ module Contrast
11
12
  # TeamServer to construct the method signature for the assess feature. They represent the method invoked when the
12
13
  # FindingEvent was generated.
13
14
  class FindingEventSignature
15
+ include Contrast::Components::Logger::InstanceMethods
16
+
14
17
  # @return [String] the types of the arguments in this event; may be different for each invocation of the
15
18
  # method.
16
19
  attr_reader :arg_types
@@ -73,7 +76,13 @@ module Contrast
73
76
  # @return [Hash]
74
77
  # @raise [ArgumentError]
75
78
  def to_controlled_hash
76
- validate
79
+ begin
80
+ validate
81
+ rescue ArgumentError => e
82
+ logger.error('FindingEventSignature validation failed with: ', e)
83
+ return
84
+ end
85
+
77
86
  {
78
87
  argTypes: arg_types,
79
88
  className: class_name,
@@ -4,6 +4,7 @@
4
4
  require 'base64'
5
5
  require 'contrast/agent/assess/contrast_event'
6
6
  require 'contrast/agent/assess/events/source_event'
7
+ require 'contrast/components/logger'
7
8
 
8
9
  module Contrast
9
10
  module Agent
@@ -13,6 +14,8 @@ module Contrast
13
14
  # to construct the vulnerability information for the assess feature. They indicate the type of data that the
14
15
  # event represents.
15
16
  class FindingEventSource
17
+ include Contrast::Components::Logger::InstanceMethods
18
+
16
19
  # @return [String] the name of the source
17
20
  attr_reader :name
18
21
  # @return [String] the type of the source
@@ -45,13 +48,20 @@ module Contrast
45
48
  # @return [Hash]
46
49
  # @raise [ArgumentError]
47
50
  def to_controlled_hash
48
- validate
51
+ begin
52
+ validate
53
+ rescue ArgumentError => e
54
+ logger.error('FindingEventSource validation failed with: ', e)
55
+ return
56
+ end
57
+
49
58
  {
50
59
  sourceName: name, # rubocop:disable Security/Module/Name
51
60
  sourceType: type
52
61
  }
53
62
  end
54
63
 
64
+ # @raise [ArgumentError]
55
65
  def validate
56
66
  raise(ArgumentError, "#{ self } did not have a proper type. Unable to continue.") unless type && !type.empty?
57
67
  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/logger'
5
+
4
6
  module Contrast
5
7
  module Agent
6
8
  module Reporting
@@ -9,6 +11,8 @@ module Contrast
9
11
  # to construct the vulnerability information for the assess feature. They represent the callstack at the time
10
12
  # that each FindingEvent was generated.
11
13
  class FindingEventStack
14
+ include Contrast::Components::Logger::InstanceMethods
15
+
12
16
  # @return [String] unused
13
17
  attr_reader :eval
14
18
  # @return [String] the stack frame to show in TeamServer; the value of an entry in #caller
@@ -51,7 +55,13 @@ module Contrast
51
55
  # @return [Hash]
52
56
  # @raise [ArgumentError]
53
57
  def to_controlled_hash
54
- validate
58
+ begin
59
+ validate
60
+ rescue ArgumentError => e
61
+ logger.error('FindingEventStack validation failed with: ', e)
62
+ return
63
+ end
64
+
55
65
  {
56
66
  file: file
57
67
  # eval: eval, # This is unused by the Ruby agent
@@ -2,6 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'contrast/agent/assess/tag'
5
+ require 'contrast/components/logger'
5
6
 
6
7
  module Contrast
7
8
  module Agent
@@ -11,6 +12,8 @@ module Contrast
11
12
  # TeamServer to construct the vulnerability information for the assess feature. They represent those parts of the
12
13
  # objects that are tracked because of a security relevant operation acting on them.
13
14
  class FindingEventTaintRange
15
+ include Contrast::Components::Logger::InstanceMethods
16
+
14
17
  # @return [String] the range (inclusive:exclusive), that this tag covers.
15
18
  attr_reader :range
16
19
  # @return [String] the type of action this tag represents.
@@ -41,13 +44,20 @@ module Contrast
41
44
  # @return [Hash]
42
45
  # @raise [ArgumentError]
43
46
  def to_controlled_hash
44
- validate
47
+ begin
48
+ validate
49
+ rescue ArgumentError => e
50
+ logger.error('FindingEventTaintRange validation failed with: ', e)
51
+ return
52
+ end
53
+
45
54
  {
46
55
  range: range,
47
56
  tag: tag
48
57
  }
49
58
  end
50
59
 
60
+ # @raise [ArgumentError]
51
61
  def validate
52
62
  unless range && !range.empty?
53
63
  raise(ArgumentError, "#{ self } did not have a proper range. Unable to continue.")
@@ -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/logger'
5
+
4
6
  module Contrast
5
7
  module Agent
6
8
  module Reporting
@@ -9,6 +11,8 @@ module Contrast
9
11
  # HTTP information for the assess feature. They represent the literal request made that resulted in the
10
12
  # vulnerability being triggered.
11
13
  class FindingRequest
14
+ include Contrast::Components::Logger::InstanceMethods
15
+
12
16
  # @return [String] the body of this request
13
17
  attr_reader :body
14
18
  # @return [Hash<String,Array<String>>] the headers of this request
@@ -68,7 +72,13 @@ module Contrast
68
72
  # @return [Hash]
69
73
  # @raise [ArgumentError]
70
74
  def to_controlled_hash
71
- validate
75
+ begin
76
+ validate
77
+ rescue ArgumentError => e
78
+ logger.error('FindingRequest validation failed with: ', e)
79
+ return
80
+ end
81
+
72
82
  {
73
83
  body: body,
74
84
  headers: headers,
@@ -2,6 +2,8 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'contrast/api/dtm.pb'
5
+ require 'contrast/utils/string_utils'
6
+ require 'contrast/components/logger'
5
7
 
6
8
  module Contrast
7
9
  module Agent
@@ -16,41 +18,31 @@ module Contrast
16
18
  # @attr_reader file [String] the name of the Gem. Required for reporting.
17
19
  # @attr_reader hash [String] the Sha256 of the Gem, matching its hash in RubyGems. Required for reporting.
18
20
  # @attr_reader internal_date [Integer] the time, in ms, when the Gem was published. Required for reporting.
19
- # @attr_reader manifest [String] the YAML form of the Gem's specification.
21
+ # @attr_accessor manifest [String] the YAML form of the Gem's specification.
20
22
  # @attr_reader tags [String] Inventory tags set by the user via configuration.
21
23
  # @attr_reader url [String] The homepage of the Gem.
22
24
  # @attr_reader version [String] The version of the Gem.
23
25
  class LibraryDiscovery
26
+ include Contrast::Components::Logger::InstanceMethods
27
+
28
+ StringUtils = Contrast::Utils::StringUtils
29
+
24
30
  # required attributes
25
31
  attr_reader :external_date, :file, :hash, :internal_date
26
32
  # optional attributes
27
- attr_reader :class_count, :manifest, :tags, :url, :version
28
-
29
- class << self
30
- # Convert a DTM for SpeedRacer to an Event for TeamServer.
31
- #
32
- # @param library_dtm [Contrast::Api::Dtm::Library]
33
- # @return [Contrast::Agent::Reporting::LibraryDiscovery]
34
- def convert library_dtm
35
- report = new
36
- report.attach_data(library_dtm)
37
- report
38
- end
39
- end
33
+ attr_reader :class_count, :tags, :url, :version
34
+ attr_accessor :manifest
40
35
 
41
- # Attach the data from the protobuf models to this reporter so that it can be sent to TeamServer directly
42
- #
43
- # @param library_dtm [Contrast::Api::Dtm::Library]
44
- def attach_data library_dtm
45
- @class_count = library_dtm.class_count
46
- @external_date = library_dtm.external_ms
47
- @file = library_dtm.file_path
48
- @hash = library_dtm.hash_code
49
- @internal_date = library_dtm.internal_ms
50
- @manifest = library_dtm.manifest
36
+ def initialize digest, spec
37
+ @file = StringUtils.force_utf8(spec.name) # rubocop:disable Security/Module/Name
38
+ @hash = StringUtils.force_utf8(digest)
39
+ @version = StringUtils.force_utf8(spec.version)
40
+ @manifest = StringUtils.force_utf8(StringUtils.force_utf8(spec.to_yaml.to_s))
41
+ @external_date = (spec.date.to_f * 1000.0).to_i
42
+ @internal_date = @external_date
43
+ @url = StringUtils.force_utf8(spec.homepage)
44
+ @class_count = Contrast::Utils::Sha256Builder.instance.files(spec.full_gem_path.to_s).length
51
45
  @tags = Contrast::INVENTORY.tags
52
- @url = library_dtm.url
53
- @version = library_dtm.version
54
46
  end
55
47
 
56
48
  # Convert the instance variables on the class, and other information, into the identifiers required for
@@ -59,8 +51,14 @@ module Contrast
59
51
  # @return [Hash]
60
52
  # @raise [ArgumentError]
61
53
  def to_controlled_hash
62
- validate
63
- msg = {
54
+ begin
55
+ validate
56
+ rescue ArgumentError => e
57
+ logger.error('LibraryDiscovery validation failed with: ', e)
58
+ return
59
+ end
60
+
61
+ {
64
62
  classCount: class_count,
65
63
  externalDate: external_date,
66
64
  file: file,
@@ -68,10 +66,9 @@ module Contrast
68
66
  internalDate: internal_date,
69
67
  manifest: manifest,
70
68
  url: url,
71
- version: version
72
- }
73
- msg[:tags] = tags if tags
74
- msg
69
+ version: version,
70
+ tags: tags
71
+ }.compact
75
72
  end
76
73
 
77
74
  # Ensure the required fields are present.
@@ -1,11 +1,15 @@
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
  module Reporting
7
9
  # The usage, meaning loaded files, of a library seen during this request
8
10
  class LibraryUsageObservation
11
+ include Contrast::Components::Logger::InstanceMethods
12
+
9
13
  # @param [String] Sha256Sum of library as identified by the agent
10
14
  attr_accessor :id
11
15
  # @param [Array<String>] List of file paths that have been loaded out of or executed by the library
@@ -18,14 +22,22 @@ module Contrast
18
22
  @names = class_names
19
23
  end
20
24
 
25
+ # @raise [ArgumentError]
21
26
  def to_controlled_hash
22
- validate
27
+ begin
28
+ validate
29
+ rescue ArgumentError => e
30
+ logger.error('LibraryUsageObservation validation failed with: ', e)
31
+ return
32
+ end
33
+
23
34
  {
24
35
  id: @id,
25
36
  names: @names
26
37
  }
27
38
  end
28
39
 
40
+ # @raise [ArgumentError]
29
41
  def validate
30
42
  raise(ArgumentError, "#{ self } did not have a proper id. Unable to continue.") unless id
31
43
  raise(ArgumentError, "#{ self } did not have a proper names. Unable to continue.") if names.empty?
@@ -3,15 +3,16 @@
3
3
 
4
4
  require 'contrast/agent/reporting/reporting_events/application_reporting_event'
5
5
  require 'contrast/agent/reporting/reporting_events/library_usage_observation'
6
+ require 'contrast/components/logger'
6
7
 
7
8
  module Contrast
8
9
  module Agent
9
10
  module Reporting
10
11
  # List of libraries that have been observed to have something loaded or executed.
11
- #
12
12
  class ObservedLibraryUsage < Contrast::Agent::Reporting::ApplicationReportingEvent
13
- # @attr_reader observations - Array[Contrast::Agent::Reporting::LibraryUsageObservation]
14
- # - Hash of LibraryUsageObservations
13
+ include Contrast::Components::Logger::InstanceMethods
14
+
15
+ # @return Array[Contrast::Agent::Reporting::LibraryUsageObservation]
15
16
  attr_reader :observations
16
17
 
17
18
  def initialize
@@ -25,17 +26,19 @@ module Contrast
25
26
  end
26
27
 
27
28
  def to_controlled_hash
28
- validate
29
+ begin
30
+ validate
31
+ rescue ArgumentError => e
32
+ logger.error('ObservedLibraryUsage validation failed with: ', e)
33
+ return
34
+ end
35
+
29
36
  { observations: @observations.map(&:to_controlled_hash) }
30
37
  end
31
38
 
32
39
  def validate
33
40
  raise(ArgumentError, "#{ self } did not have observations. Unable to continue.") if observations.empty?
34
41
  end
35
-
36
- def clear
37
- @observations = []
38
- end
39
42
  end
40
43
  end
41
44
  end
@@ -16,6 +16,8 @@ module Contrast
16
16
  # includes the literal URL and HTTP Verb used to invoke them, as they must have been called at this point to be
17
17
  # recorded.
18
18
  class ObservedRoute < Contrast::Agent::Reporting::ApplicationReportingEvent
19
+ include Contrast::Components::Logger::InstanceMethods
20
+
19
21
  # @param [String] the method signature used to uniquely identify the coverage report.
20
22
  attr_accessor :signature
21
23
  # @param [String] the normalized URL used to access the method in the route.
@@ -45,18 +47,23 @@ module Contrast
45
47
  # @return [Hash]
46
48
  # @raise [ArgumentError]
47
49
  def to_controlled_hash
48
- validate
49
- rc_hash = {
50
+ begin
51
+ validate
52
+ rescue ArgumentError => e
53
+ logger.error('ObservedRoute validation failed with: ', e)
54
+ return
55
+ end
56
+
57
+ {
50
58
  session_id: ::Contrast::ASSESS.session_id,
51
59
  sources: @sources.map(&:to_controlled_hash),
52
60
  signature: @signature,
53
61
  verb: @verb,
54
62
  url: @url
55
- }
56
- rc_hash.delete(:verb) unless @verb
57
- rc_hash
63
+ }.compact
58
64
  end
59
65
 
66
+ # @raise [ArgumentError]
60
67
  def validate
61
68
  raise(ArgumentError, "#{ self } did not have a proper sources. Unable to continue.") if @sources.nil?
62
69
  raise(ArgumentError, "#{ self } did not have a proper signature. Unable to continue.") unless signature
@@ -38,7 +38,13 @@ module Contrast
38
38
  # @return [Hash]
39
39
  # @raise [ArgumentError]
40
40
  def to_controlled_hash
41
- validate
41
+ begin
42
+ validate
43
+ rescue ArgumentError => e
44
+ logger.error('PreflightMessage validation failed with: ', e)
45
+ return
46
+ end
47
+
42
48
  {
43
49
  code: CODE,
44
50
  app_language: @app_language,
@@ -51,6 +57,7 @@ module Contrast
51
57
  }
52
58
  end
53
59
 
60
+ # @raise [ArgumentError]
54
61
  def validate
55
62
  raise(ArgumentError, "#{ cs__class } did not have a proper data. Unable to continue.") unless data
56
63
  unless @app_name
@@ -14,6 +14,8 @@ module Contrast
14
14
  #
15
15
  # @abstract
16
16
  class ReportingEvent
17
+ include Contrast::Components::Logger::InstanceMethods
18
+
17
19
  # @return [String] the endpoint, with host, to which this event should be sent
18
20
  attr_reader :event_endpoint
19
21
  # @return event_method [Symbol] the HTTP method to use to send this event
@@ -35,7 +37,13 @@ module Contrast
35
37
  # @return [Hash]
36
38
  # @raise [ArgumentError]
37
39
  def to_controlled_hash
38
- validate
40
+ begin
41
+ validate
42
+ rescue ArgumentError => e
43
+ logger.error('ReportingEvent validation failed with: ', e)
44
+ return
45
+ end
46
+
39
47
  {}
40
48
  end
41
49
 
@@ -3,6 +3,7 @@
3
3
 
4
4
  require 'contrast/agent/reporting/reporting_events/route_discovery_observation'
5
5
  require 'contrast/api/dtm.pb'
6
+ require 'contrast/components/logger'
6
7
 
7
8
  module Contrast
8
9
  module Agent
@@ -17,6 +18,8 @@ module Contrast
17
18
  # @attr_reader signature [String] the unique identifier for this route; typically the method signature. Required
18
19
  # for reporting.
19
20
  class RouteDiscovery
21
+ include Contrast::Components::Logger::InstanceMethods
22
+
20
23
  # required attributes
21
24
  attr_reader :observations, :signature
22
25
 
@@ -47,7 +50,13 @@ module Contrast
47
50
  # @return [Hash]
48
51
  # @raise [ArgumentError]
49
52
  def to_controlled_hash
50
- validate
53
+ begin
54
+ validate
55
+ rescue ArgumentError => e
56
+ logger.error('RouteDiscovery validation failed with: ', e)
57
+ return
58
+ end
59
+
51
60
  {
52
61
  count: 0, # we have this to make TS happy
53
62
  observations: @observations.map(&:to_controlled_hash),