lib/contrast/agent/assess/contrast_event.rb in contrast-agent-3.10.2 vs lib/contrast/agent/assess/contrast_event.rb in contrast-agent-3.11.0
- old
+ new
@@ -1,10 +1,16 @@
# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
# frozen_string_literal: true
+cs__scoped_require 'contrast/utils/assess/tracking_util'
cs__scoped_require 'contrast/utils/class_util'
+cs__scoped_require 'contrast/utils/duck_utils'
+cs__scoped_require 'contrast/utils/object_share'
cs__scoped_require 'contrast/utils/prevent_serialization'
+cs__scoped_require 'contrast/utils/stack_trace_utils'
+cs__scoped_require 'contrast/utils/string_utils'
+cs__scoped_require 'contrast/utils/timer'
module Contrast
module Agent
module Assess
# This class holds the data about an event in the application
@@ -51,12 +57,11 @@
original
end
end
end
- attr_accessor :source_name
- attr_reader :event_id, :source_type, :parent_ids
+ attr_reader :event_id, :parent_ids
# We need this to track the parent id's of events to build up a flow
# chart of the finding
@atomic_id = 0
@atomic_mutex = Mutex.new
@@ -67,29 +72,27 @@
rescue StandardError
@atomic_id = 1
end
end
- def initialize policy_node, tagged, object, ret, args, invoked = 0, source_type = nil, source_name = nil
- @caller = caller_locations(get_call_start(policy_node, invoked), 10)
+ def initialize policy_node, tagged, object, ret, args
@policy_node = policy_node
+ # so long as this event is built in a factory, we know Contrast Code
+ # will be the first three events
+ @caller = caller(3, 20)
@time = Contrast::Utils::Timer.now_ms
@thread = Thread.current.object_id
- @source_type = source_type
- @source_name = source_name
# These methods rely on the above being set. Don't move them!
@event_id = Contrast::Agent::Assess::ContrastEvent.next_atomic_id
@parent_ids = find_parent_ids(policy_node, object, ret, args)
snapshot(tagged, object, ret, args)
end
# Parent IDs are the event ids of all the sources of this event which
# were tracked prior to this event occurring
def find_parent_ids policy_node, object, ret, args
- return if policy_node.is_a?(Contrast::Agent::Assess::Policy::SourceNode)
-
mapped = policy_node.sources.map do |source|
value_of_source(source, object, ret, args)
end
selected = mapped.select do |source|
source &&
@@ -135,10 +138,12 @@
# I know we're creating an extra string here since we replace the safe
# one w/ a dup, but good enough for now. Trying not to make this too
# complicated. - HM 8/8/19
def save_target_arg target, tagged
+ return if @args.cs__frozen?
+
if target.is_a?(Integer)
@args[target] = cs__class.safe_dup(tagged)
return
end
@@ -170,31 +175,10 @@
end
end
end
end
- # each policy_node has a certain number of levels down it calls
- # before getting here. since we know them, we can skip
- # right to the part of the stack we care about.
- #
- # Note: if our callstack changes, this number has to change
- def get_call_start policy_node, invoked
- # TODO: RUBY-440 audit these numbers to get stacktraces to render
- # properly
- base = case policy_node
- when Contrast::Agent::Assess::Policy::SourceNode
- 6
- when Contrast::Agent::Assess::Policy::PropagationNode
- 7
- when Contrast::Agent::Assess::Policy::TriggerNode
- 7
- else
- 2
- end
- base + invoked
- end
-
# Convert this event into a DTM that TeamServer can consume
def to_dtm_event
event = Contrast::Api::Dtm::TraceEvent.new
# Figure out what the target of this event was. It's a little
@@ -218,53 +202,23 @@
taint_ranges.each do |range|
event.taint_ranges << range
end
# We delayed doing this as long as possible b/c it's expensive
- stack = Contrast::Utils::StackTraceUtils.to_dtm_stack(
- stack_locations: @caller,
- rasp_element: false)
- stack.each do |frame|
- event.stack << frame
- end
+ stack = Contrast::Utils::StackTraceUtils.build_assess_stack_array(@caller)
+ event.stack += stack
- event.field_name = Contrast::Utils::StringUtils.force_utf8(source_name)
-
- event_source_dtm = build_event_source_dtm
- event.event_sources << event_source_dtm if event_source_dtm
-
event.object_id = event_id.to_i
- @parent_ids&.each do |id|
+ parent_ids&.each do |id|
parent = Contrast::Api::Dtm::ParentObjectId.new
parent.id = id.to_i
event.parent_object_ids << parent
end
# not to be confused w/ the partial signature
build_complete_signature(event)
event
- end
-
- def forced_source_type
- @_forced_source_type ||= Contrast::Utils::StringUtils.force_utf8(source_type)
- end
-
- def forced_source_name
- @_forced_source_name ||= Contrast::Utils::StringUtils.force_utf8(source_name)
- end
-
- # Probably only for source events, but we'll go
- # with source_type instead. java & .net support source_type
- # in propagation events, so we'll future proof this
- def build_event_source_dtm
- # You can have a source w/o a name, but not w/o a type
- return unless source_type
-
- dtm = Contrast::Api::Dtm::TraceEventSource.new
- dtm.type = forced_source_type
- dtm.name = forced_source_name
- dtm
end
# We're not going to build the signature string here, b/c we have all
# the composite pieces of it. Instead, we're going to let TeamServer
# render this for us.