Skip to content

Commit

Permalink
Move events from SecurityEngine::Runner to Context
Browse files Browse the repository at this point in the history
  • Loading branch information
Strech committed Jan 15, 2025
1 parent d636161 commit 7a8e713
Show file tree
Hide file tree
Showing 13 changed files with 37 additions and 29 deletions.
6 changes: 2 additions & 4 deletions lib/datadog/appsec/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ class Context
ActiveContextError = Class.new(StandardError)
WAFMetrics = Struct.new(:timeouts, :duration_ns, :duration_ext_ns, keyword_init: true)

attr_reader :trace, :span, :waf_metrics

# NOTE: This is an intermediate state and will be changed
attr_reader :waf_runner
attr_reader :trace, :span, :events, :waf_metrics

class << self
def activate(context)
Expand All @@ -35,6 +32,7 @@ def active
def initialize(trace, span, security_engine)
@trace = trace
@span = span
@events = []
@security_engine = security_engine
@waf_runner = security_engine.new_runner
@waf_metrics = WAFMetrics.new(timeouts: 0, duration_ns: 0, duration_ext_ns: 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def detect_sql_injection(sql, adapter_name)
sql: sql,
actions: result.actions
}
context.waf_runner.events << event
context.events << event
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/datadog/appsec/contrib/graphql/gateway/watcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def watch_multiplex(gateway = Instrumentation.gateway)
}

Datadog::AppSec::Event.tag_and_keep!(context, result)
context.waf_runner.events << event
context.events << event
end

block = GraphQL::Reactive::Multiplex.publish(engine, gateway_multiplex)
Expand Down
6 changes: 3 additions & 3 deletions lib/datadog/appsec/contrib/rack/gateway/watcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def watch_request(gateway = Instrumentation.gateway)
# We want to keep the trace in case of security event
context.trace.keep! if context.trace
Datadog::AppSec::Event.tag_and_keep!(context, result)
context.waf_runner.events << event
context.events << event
end
end

Expand Down Expand Up @@ -74,7 +74,7 @@ def watch_response(gateway = Instrumentation.gateway)
# We want to keep the trace in case of security event
context.trace.keep! if context.trace
Datadog::AppSec::Event.tag_and_keep!(context, result)
context.waf_runner.events << event
context.events << event
end
end

Expand Down Expand Up @@ -105,7 +105,7 @@ def watch_request_body(gateway = Instrumentation.gateway)
# We want to keep the trace in case of security event
context.trace.keep! if context.trace
Datadog::AppSec::Event.tag_and_keep!(context, result)
context.waf_runner.events << event
context.events << event
end
end

Expand Down
6 changes: 3 additions & 3 deletions lib/datadog/appsec/contrib/rack/request_middleware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,19 @@ def call(env)
http_response = AppSec::Response.negotiate(env, block_actions).to_rack if block_actions

if AppSec.api_security_enabled?
ctx.waf_runner.events << {
ctx.events << {
trace: ctx.trace,
span: ctx.span,
waf_result: ctx.extract_schema,
}
end

ctx.waf_runner.events.each do |e|
ctx.events.each do |e|
e[:response] ||= gateway_response
e[:request] ||= gateway_request
end

AppSec::Event.record(ctx.span, *ctx.waf_runner.events)
AppSec::Event.record(ctx.span, *ctx.events)

http_response
ensure
Expand Down
2 changes: 1 addition & 1 deletion lib/datadog/appsec/contrib/rails/gateway/watcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def watch_request_action(gateway = Instrumentation.gateway)
# We want to keep the trace in case of security event
context.trace.keep! if context.trace
Datadog::AppSec::Event.tag_and_keep!(context, result)
context.waf_runner.events << event
context.events << event
end
end

Expand Down
4 changes: 2 additions & 2 deletions lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def watch_request_dispatch(gateway = Instrumentation.gateway)
# We want to keep the trace in case of security event
context.trace.keep! if context.trace
Datadog::AppSec::Event.tag_and_keep!(context, result)
context.waf_runner.events << event
context.events << event
end
end

Expand Down Expand Up @@ -72,7 +72,7 @@ def watch_request_routed(gateway = Instrumentation.gateway)
# We want to keep the trace in case of security event
context.trace.keep! if context.trace
Datadog::AppSec::Event.tag_and_keep!(context, result)
context.waf_runner.events << event
context.events << event
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/datadog/appsec/monitor/gateway/watcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def watch_user_id(gateway = Instrumentation.gateway)
# We want to keep the trace in case of security event
context.trace.keep! if context.trace
Datadog::AppSec::Event.tag_and_keep!(context, result)
context.waf_runner.events << event
context.events << event
end
end

Expand Down
4 changes: 4 additions & 0 deletions sig/datadog/appsec/context.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ module Datadog

@span: Tracing::SpanOperation

@events: ::Array[untyped]

@security_engine: Processor

@waf_runner: SecurityEngine::Runner
Expand All @@ -31,6 +33,8 @@ module Datadog

attr_reader span: Tracing::SpanOperation

attr_reader events: ::Array[untyped]

attr_reader waf_runner: SecurityEngine::Runner

attr_reader waf_metrics: WAFMetrics
Expand Down
8 changes: 4 additions & 4 deletions spec/datadog/appsec/context_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
'server.request.headers.no_cookies' => { 'user-agent' => 'Nessus SOAP' }
}

Array.new(3) { context.run_waf(persistent_data, {}, 1_000) }
Array.new(3) { context.run_waf(persistent_data, {}, 10_000) }
end

it 'returns a single match and rest is ok' do
Expand All @@ -110,8 +110,8 @@
}

[
context.run_waf(persistent_data_1, {}, 1_000),
context.run_waf(persistent_data_2, {}, 1_000),
context.run_waf(persistent_data_1, {}, 10_000),
context.run_waf(persistent_data_2, {}, 10_000),
]
end

Expand Down Expand Up @@ -142,7 +142,7 @@
persistent_data = {
'server.request.headers.no_cookies' => { 'user-agent' => 'Nessus SOAP' }
}
Array.new(3) { context.run_waf(persistent_data, {}, 1_000) }
Array.new(3) { context.run_waf(persistent_data, {}, 10_000) }
end

it 'returns metrics containing 0 timeouts and cumulative durations' do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,12 @@
end

it 'adds an event to processor context if waf result is a match' do
expect(Datadog::AppSec.active_context).to receive(:run_rasp)
.and_return(instance_double(Datadog::AppSec::SecurityEngine::Result::Match, actions: {}))
result = Datadog::AppSec::SecurityEngine::Result::Match.new(
events: [], actions: {}, derivatives: {}, timeout: false, duration_ns: 0, duration_ext_ns: 0
)

expect(Datadog::AppSec.active_context.waf_runner.events).to receive(:<<).and_call_original
expect(Datadog::AppSec.active_context).to receive(:run_rasp).and_return(result)
expect(Datadog::AppSec.active_context.events).to receive(:<<).and_call_original

User.where(name: 'Bob').to_a
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,12 @@
end

it 'adds an event to processor context if waf result is a match' do
expect(Datadog::AppSec.active_context).to receive(:run_rasp)
.and_return(instance_double(Datadog::AppSec::SecurityEngine::Result::Match, actions: {}))
result = Datadog::AppSec::SecurityEngine::Result::Match.new(
events: [], actions: {}, derivatives: {}, timeout: false, duration_ns: 0, duration_ext_ns: 0
)

expect(Datadog::AppSec.active_context.waf_runner.events).to receive(:<<).and_call_original
expect(Datadog::AppSec.active_context).to receive(:run_rasp).and_return(result)
expect(Datadog::AppSec.active_context.events).to receive(:<<).and_call_original

User.where(name: 'Bob').to_a
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,12 @@
end

it 'adds an event to processor context if waf result is a match' do
expect(Datadog::AppSec.active_context).to receive(:run_rasp)
.and_return(instance_double(Datadog::AppSec::SecurityEngine::Result::Match, actions: {}))
result = Datadog::AppSec::SecurityEngine::Result::Match.new(
events: [], actions: {}, derivatives: {}, timeout: false, duration_ns: 0, duration_ext_ns: 0
)

expect(Datadog::AppSec.active_context.waf_runner.events).to receive(:<<).and_call_original
expect(Datadog::AppSec.active_context).to receive(:run_rasp).and_return(result)
expect(Datadog::AppSec.active_context.events).to receive(:<<).and_call_original

User.where(name: 'Bob').to_a
end
Expand Down

0 comments on commit 7a8e713

Please sign in to comment.