diff --git a/lib/datadog/appsec/context.rb b/lib/datadog/appsec/context.rb index cf63ab4a57a..393cad27069 100644 --- a/lib/datadog/appsec/context.rb +++ b/lib/datadog/appsec/context.rb @@ -7,10 +7,10 @@ module AppSec class Context ActiveContextError = Class.new(StandardError) - # XXX: Continue from here: - # 1. Replace naming of processor_context into waf_runner - # 2. Replace calls of waf run - attr_reader :trace, :span, :processor_context + attr_reader :trace, :span + + # NOTE: This is an intermediate state and will be changed + attr_reader :waf_runner class << self def activate(context) @@ -36,9 +36,6 @@ def initialize(trace, span, security_engine) @span = span @security_engine = security_engine @waf_runner = security_engine.new_context - - # FIXME: Left for compatibility now - @processor_context = @waf_runner end def run_waf(persistent_data, ephemeral_data, timeout = WAF::LibDDWAF::DDWAF_RUN_TIMEOUT) diff --git a/lib/datadog/appsec/contrib/active_record/instrumentation.rb b/lib/datadog/appsec/contrib/active_record/instrumentation.rb index 57334c93896..41a8e80523c 100644 --- a/lib/datadog/appsec/contrib/active_record/instrumentation.rb +++ b/lib/datadog/appsec/contrib/active_record/instrumentation.rb @@ -23,7 +23,7 @@ def detect_sql_injection(sql, adapter_name) } waf_timeout = Datadog.configuration.appsec.waf_timeout - result = context.processor_context.run({}, ephemeral_data, waf_timeout) + result = context.run_rasp(Ext::RASP_SQLI, {}, ephemeral_data, waf_timeout) if result.status == :match Datadog::AppSec::Event.tag_and_keep!(context, result) @@ -35,7 +35,7 @@ def detect_sql_injection(sql, adapter_name) sql: sql, actions: result.actions } - context.processor_context.events << event + context.waf_runner.events << event end end diff --git a/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb b/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb index cb00eff045c..a360e21852e 100644 --- a/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +++ b/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb @@ -28,7 +28,7 @@ def watch_multiplex(gateway = Instrumentation.gateway) engine = AppSec::Reactive::Engine.new if context - GraphQL::Reactive::Multiplex.subscribe(engine, context.processor_context) do |result| + GraphQL::Reactive::Multiplex.subscribe(engine, context) do |result| event = { waf_result: result, trace: context.trace, @@ -38,7 +38,7 @@ def watch_multiplex(gateway = Instrumentation.gateway) } Datadog::AppSec::Event.tag_and_keep!(context, result) - context.processor_context.events << event + context.waf_runner.events << event end block = GraphQL::Reactive::Multiplex.publish(engine, gateway_multiplex) diff --git a/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb b/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb index cfbf31dc1b8..ec6380cff52 100644 --- a/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +++ b/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb @@ -20,7 +20,7 @@ def self.publish(engine, gateway_multiplex) end end - def self.subscribe(engine, waf_context) + def self.subscribe(engine, context) engine.subscribe(*ADDRESSES) do |*values| Datadog.logger.debug { "reacted to #{ADDRESSES.inspect}: #{values.inspect}" } arguments = values[0] @@ -30,7 +30,7 @@ def self.subscribe(engine, waf_context) } waf_timeout = Datadog.configuration.appsec.waf_timeout - result = waf_context.run(persistent_data, {}, waf_timeout) + result = context.run_waf(persistent_data, {}, waf_timeout) next if result.status != :match diff --git a/lib/datadog/appsec/contrib/rack/gateway/watcher.rb b/lib/datadog/appsec/contrib/rack/gateway/watcher.rb index 43f111795d4..f9616c5cbfa 100644 --- a/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +++ b/lib/datadog/appsec/contrib/rack/gateway/watcher.rb @@ -29,7 +29,7 @@ def watch_request(gateway = Instrumentation.gateway) context = gateway_request.env[Datadog::AppSec::Ext::CONTEXT_KEY] engine = AppSec::Reactive::Engine.new - Rack::Reactive::Request.subscribe(engine, context.processor_context) do |result| + Rack::Reactive::Request.subscribe(engine, context) do |result| if result.status == :match # TODO: should this hash be an Event instance instead? event = { @@ -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.processor_context.events << event + context.waf_runner.events << event end end @@ -67,7 +67,7 @@ def watch_response(gateway = Instrumentation.gateway) context = gateway_response.context engine = AppSec::Reactive::Engine.new - Rack::Reactive::Response.subscribe(engine, context.processor_context) do |result| + Rack::Reactive::Response.subscribe(engine, context) do |result| if result.status == :match # TODO: should this hash be an Event instance instead? event = { @@ -81,7 +81,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.processor_context.events << event + context.waf_runner.events << event end end @@ -105,7 +105,7 @@ def watch_request_body(gateway = Instrumentation.gateway) context = gateway_request.env[Datadog::AppSec::Ext::CONTEXT_KEY] engine = AppSec::Reactive::Engine.new - Rack::Reactive::RequestBody.subscribe(engine, context.processor_context) do |result| + Rack::Reactive::RequestBody.subscribe(engine, context) do |result| if result.status == :match # TODO: should this hash be an Event instance instead? event = { @@ -119,7 +119,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.processor_context.events << event + context.waf_runner.events << event end end diff --git a/lib/datadog/appsec/contrib/rack/reactive/request.rb b/lib/datadog/appsec/contrib/rack/reactive/request.rb index 78074268af6..31333851412 100644 --- a/lib/datadog/appsec/contrib/rack/reactive/request.rb +++ b/lib/datadog/appsec/contrib/rack/reactive/request.rb @@ -30,7 +30,7 @@ def self.publish(engine, gateway_request) end end - def self.subscribe(engine, waf_context) + def self.subscribe(engine, context) engine.subscribe(*ADDRESSES) do |*values| Datadog.logger.debug { "reacted to #{ADDRESSES.inspect}: #{values.inspect}" } @@ -53,7 +53,7 @@ def self.subscribe(engine, waf_context) } waf_timeout = Datadog.configuration.appsec.waf_timeout - result = waf_context.run(persistent_data, {}, waf_timeout) + result = context.run_waf(persistent_data, {}, waf_timeout) next if result.status != :match diff --git a/lib/datadog/appsec/contrib/rack/reactive/request_body.rb b/lib/datadog/appsec/contrib/rack/reactive/request_body.rb index 57395ac83b8..0cf74aef33f 100644 --- a/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +++ b/lib/datadog/appsec/contrib/rack/reactive/request_body.rb @@ -21,7 +21,7 @@ def self.publish(engine, gateway_request) end end - def self.subscribe(engine, waf_context) + def self.subscribe(engine, context) engine.subscribe(*ADDRESSES) do |*values| Datadog.logger.debug { "reacted to #{ADDRESSES.inspect}: #{values.inspect}" } body = values[0] @@ -31,7 +31,7 @@ def self.subscribe(engine, waf_context) } waf_timeout = Datadog.configuration.appsec.waf_timeout - result = waf_context.run(persistent_data, {}, waf_timeout) + result = context.run_waf(persistent_data, {}, waf_timeout) next if result.status != :match diff --git a/lib/datadog/appsec/contrib/rack/reactive/response.rb b/lib/datadog/appsec/contrib/rack/reactive/response.rb index 8c0cd706d26..9eca3e0157b 100644 --- a/lib/datadog/appsec/contrib/rack/reactive/response.rb +++ b/lib/datadog/appsec/contrib/rack/reactive/response.rb @@ -22,7 +22,7 @@ def self.publish(engine, gateway_response) end end - def self.subscribe(engine, waf_context) + def self.subscribe(engine, context) engine.subscribe(*ADDRESSES) do |*values| Datadog.logger.debug { "reacted to #{ADDRESSES.inspect}: #{values.inspect}" } @@ -37,7 +37,7 @@ def self.subscribe(engine, waf_context) } waf_timeout = Datadog.configuration.appsec.waf_timeout - result = waf_context.run(persistent_data, {}, waf_timeout) + result = context.run_waf(persistent_data, {}, waf_timeout) next if result.status != :match diff --git a/lib/datadog/appsec/contrib/rack/request_middleware.rb b/lib/datadog/appsec/contrib/rack/request_middleware.rb index 33e1e121bca..6aa14798a19 100644 --- a/lib/datadog/appsec/contrib/rack/request_middleware.rb +++ b/lib/datadog/appsec/contrib/rack/request_middleware.rb @@ -94,22 +94,22 @@ def call(env) _response_return, response_response = Instrumentation.gateway.push('rack.response', gateway_response) - result = ctx.processor_context.extract_schema + result = ctx.waf_runner.extract_schema if result - ctx.processor_context.events << { + ctx.waf_runner.events << { trace: ctx.trace, span: ctx.span, waf_result: result, } end - ctx.processor_context.events.each do |e| + ctx.waf_runner.events.each do |e| e[:response] ||= gateway_response e[:request] ||= gateway_request end - AppSec::Event.record(ctx.span, *ctx.processor_context.events) + AppSec::Event.record(ctx.span, *ctx.waf_runner.events) if response_response blocked_event = response_response.find { |action, _options| action == :block } @@ -209,7 +209,7 @@ def add_request_tags(context, env) def add_waf_runtime_tags(context) span = context.span - context = context.processor_context + context = context.waf_runner return unless span && context diff --git a/lib/datadog/appsec/contrib/rails/gateway/watcher.rb b/lib/datadog/appsec/contrib/rails/gateway/watcher.rb index 4b996c4a321..05d6125871a 100644 --- a/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +++ b/lib/datadog/appsec/contrib/rails/gateway/watcher.rb @@ -25,7 +25,7 @@ def watch_request_action(gateway = Instrumentation.gateway) context = gateway_request.env[Datadog::AppSec::Ext::CONTEXT_KEY] engine = AppSec::Reactive::Engine.new - Rails::Reactive::Action.subscribe(engine, context.processor_context) do |result| + Rails::Reactive::Action.subscribe(engine, context) do |result| if result.status == :match # TODO: should this hash be an Event instance instead? event = { @@ -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.processor_context.events << event + context.waf_runner.events << event end end diff --git a/lib/datadog/appsec/contrib/rails/reactive/action.rb b/lib/datadog/appsec/contrib/rails/reactive/action.rb index 9dbe8697e51..b1589b3131e 100644 --- a/lib/datadog/appsec/contrib/rails/reactive/action.rb +++ b/lib/datadog/appsec/contrib/rails/reactive/action.rb @@ -25,7 +25,7 @@ def self.publish(engine, gateway_request) end end - def self.subscribe(engine, waf_context) + def self.subscribe(engine, context) engine.subscribe(*ADDRESSES) do |*values| Datadog.logger.debug { "reacted to #{ADDRESSES.inspect}: #{values.inspect}" } body = values[0] @@ -37,7 +37,7 @@ def self.subscribe(engine, waf_context) } waf_timeout = Datadog.configuration.appsec.waf_timeout - result = waf_context.run(persistent_data, {}, waf_timeout) + result = context.run_waf(persistent_data, {}, waf_timeout) next if result.status != :match diff --git a/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb b/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb index 4492e7767f4..615f326affc 100644 --- a/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +++ b/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb @@ -27,7 +27,7 @@ def watch_request_dispatch(gateway = Instrumentation.gateway) context = gateway_request.env[Datadog::AppSec::Ext::CONTEXT_KEY] engine = AppSec::Reactive::Engine.new - Rack::Reactive::RequestBody.subscribe(engine, context.processor_context) do |result| + Rack::Reactive::RequestBody.subscribe(engine, context) do |result| if result.status == :match # TODO: should this hash be an Event instance instead? event = { @@ -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.processor_context.events << event + context.waf_runner.events << event end end @@ -65,7 +65,7 @@ def watch_request_routed(gateway = Instrumentation.gateway) context = gateway_request.env[Datadog::AppSec::Ext::CONTEXT_KEY] engine = AppSec::Reactive::Engine.new - Sinatra::Reactive::Routed.subscribe(engine, context.processor_context) do |result| + Sinatra::Reactive::Routed.subscribe(engine, context) do |result| if result.status == :match # TODO: should this hash be an Event instance instead? event = { @@ -79,7 +79,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.processor_context.events << event + context.waf_runner.events << event end end diff --git a/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb b/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb index e34dfb4ccb3..7227d0539d6 100644 --- a/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +++ b/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb @@ -22,7 +22,7 @@ def self.publish(engine, data) end end - def self.subscribe(engine, waf_context) + def self.subscribe(engine, context) engine.subscribe(*ADDRESSES) do |*values| Datadog.logger.debug { "reacted to #{ADDRESSES.inspect}: #{values.inspect}" } path_params = values[0] @@ -32,7 +32,7 @@ def self.subscribe(engine, waf_context) } waf_timeout = Datadog.configuration.appsec.waf_timeout - result = waf_context.run(persistent_data, {}, waf_timeout) + result = context.run_waf(persistent_data, {}, waf_timeout) next if result.status != :match diff --git a/lib/datadog/appsec/ext.rb b/lib/datadog/appsec/ext.rb index a801a394546..2c6e6f5fae3 100644 --- a/lib/datadog/appsec/ext.rb +++ b/lib/datadog/appsec/ext.rb @@ -3,6 +3,7 @@ module Datadog module AppSec module Ext + RASP_SQLI = :sql_injection INTERRUPT = :datadog_appsec_interrupt CONTEXT_KEY = 'datadog.appsec.context' ACTIVE_CONTEXT_KEY = :datadog_appsec_active_context diff --git a/lib/datadog/appsec/monitor/gateway/watcher.rb b/lib/datadog/appsec/monitor/gateway/watcher.rb index aebd8724839..2d122559a03 100644 --- a/lib/datadog/appsec/monitor/gateway/watcher.rb +++ b/lib/datadog/appsec/monitor/gateway/watcher.rb @@ -23,7 +23,7 @@ def watch_user_id(gateway = Instrumentation.gateway) context = Datadog::AppSec.active_context engine = AppSec::Reactive::Engine.new - Monitor::Reactive::SetUser.subscribe(engine, context.processor_context) do |result| + Monitor::Reactive::SetUser.subscribe(engine, context) do |result| if result.status == :match # TODO: should this hash be an Event instance instead? event = { @@ -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.processor_context.events << event + context.waf_runner.events << event end end diff --git a/lib/datadog/appsec/monitor/reactive/set_user.rb b/lib/datadog/appsec/monitor/reactive/set_user.rb index ea3128c6031..64df8931f30 100644 --- a/lib/datadog/appsec/monitor/reactive/set_user.rb +++ b/lib/datadog/appsec/monitor/reactive/set_user.rb @@ -19,7 +19,7 @@ def self.publish(engine, user) end end - def self.subscribe(engine, waf_context) + def self.subscribe(engine, context) engine.subscribe(*ADDRESSES) do |*values| Datadog.logger.debug { "reacted to #{ADDRESSES.inspect}: #{values.inspect}" } @@ -30,7 +30,7 @@ def self.subscribe(engine, waf_context) } waf_timeout = Datadog.configuration.appsec.waf_timeout - result = waf_context.run(persistent_data, {}, waf_timeout) + result = context.run_waf(persistent_data, {}, waf_timeout) next if result.status != :match diff --git a/spec/datadog/appsec/contrib/active_record/mysql2_adapter_spec.rb b/spec/datadog/appsec/contrib/active_record/mysql2_adapter_spec.rb index b43f7b15dc0..59306b5a7ba 100644 --- a/spec/datadog/appsec/contrib/active_record/mysql2_adapter_spec.rb +++ b/spec/datadog/appsec/contrib/active_record/mysql2_adapter_spec.rb @@ -15,7 +15,7 @@ let(:telemetry) { instance_double(Datadog::Core::Telemetry::Component) } let(:ruleset) { Datadog::AppSec::Processor::RuleLoader.load_rules(ruleset: :recommended, telemetry: telemetry) } let(:processor) { Datadog::AppSec::Processor.new(ruleset: ruleset, telemetry: telemetry) } - let(:context) { processor.new_context } + let(:context) { Datadog::AppSec::Context.new(trace, span, processor) } let(:span) { Datadog::Tracing::SpanOperation.new('root') } let(:trace) { Datadog::Tracing::TraceOperation.new } @@ -52,7 +52,7 @@ c.appsec.instrument :active_record end - Datadog::AppSec::Context.activate_context(trace, span, processor) + Datadog::AppSec::Context.activate(context) raise_on_rails_deprecation! end @@ -60,13 +60,14 @@ after do Datadog.configuration.reset! - Datadog::AppSec::Context.deactivate_context + Datadog::AppSec::Context.deactivate processor.finalize end it 'calls waf with correct arguments when querying using .where' do - expect(Datadog::AppSec.active_context.processor_context).to( - receive(:run).with( + expect(Datadog::AppSec.active_context).to( + receive(:run_rasp).with( + Datadog::AppSec::Ext::RASP_SQLI, {}, { 'server.db.statement' => "SELECT `users`.* FROM `users` WHERE `users`.`name` = 'Bob'", @@ -80,8 +81,9 @@ end it 'calls waf with correct arguments when querying using .find_by_sql' do - expect(Datadog::AppSec.active_context.processor_context).to( - receive(:run).with( + expect(Datadog::AppSec.active_context).to( + receive(:run_rasp).with( + Datadog::AppSec::Ext::RASP_SQLI, {}, { 'server.db.statement' => "SELECT * FROM users WHERE name = 'Bob'", @@ -95,11 +97,11 @@ end it 'adds an event to processor context if waf status is :match' do - expect(Datadog::AppSec.active_context.processor_context).to( - receive(:run).and_return(instance_double(Datadog::AppSec::WAF::Result, status: :match, actions: {})) + expect(Datadog::AppSec.active_context).to( + receive(:run_rasp).and_return(instance_double(Datadog::AppSec::WAF::Result, status: :match, actions: {})) ) - expect(Datadog::AppSec.active_context.processor_context.events).to receive(:<<).and_call_original + expect(Datadog::AppSec.active_context.waf_runner.events).to receive(:<<).and_call_original User.where(name: 'Bob').to_a end diff --git a/spec/datadog/appsec/contrib/active_record/postgresql_adapter_spec.rb b/spec/datadog/appsec/contrib/active_record/postgresql_adapter_spec.rb index 88bf4ed57fa..1a718855f00 100644 --- a/spec/datadog/appsec/contrib/active_record/postgresql_adapter_spec.rb +++ b/spec/datadog/appsec/contrib/active_record/postgresql_adapter_spec.rb @@ -15,7 +15,7 @@ let(:telemetry) { instance_double(Datadog::Core::Telemetry::Component) } let(:ruleset) { Datadog::AppSec::Processor::RuleLoader.load_rules(ruleset: :recommended, telemetry: telemetry) } let(:processor) { Datadog::AppSec::Processor.new(ruleset: ruleset, telemetry: telemetry) } - let(:context) { processor.new_context } + let(:context) { Datadog::AppSec::Context.new(trace, span, processor) } let(:span) { Datadog::Tracing::SpanOperation.new('root') } let(:trace) { Datadog::Tracing::TraceOperation.new } @@ -53,7 +53,7 @@ c.appsec.instrument :active_record end - Datadog::AppSec::Context.activate_context(trace, span, processor) + Datadog::AppSec::Context.activate(context) raise_on_rails_deprecation! end @@ -61,7 +61,7 @@ after do Datadog.configuration.reset! - Datadog::AppSec::Context.deactivate_context + Datadog::AppSec::Context.deactivate processor.finalize end @@ -72,8 +72,9 @@ 'SELECT "users".* FROM "users" WHERE "users"."name" = $1' end - expect(Datadog::AppSec.active_context.processor_context).to( - receive(:run).with( + expect(Datadog::AppSec.active_context).to( + receive(:run_rasp).with( + Datadog::AppSec::Ext::RASP_SQLI, {}, { 'server.db.statement' => expected_db_statement, @@ -87,8 +88,9 @@ end it 'calls waf with correct arguments when querying using .find_by_sql' do - expect(Datadog::AppSec.active_context.processor_context).to( - receive(:run).with( + expect(Datadog::AppSec.active_context).to( + receive(:run_rasp).with( + Datadog::AppSec::Ext::RASP_SQLI, {}, { 'server.db.statement' => "SELECT * FROM users WHERE name = 'Bob'", @@ -102,11 +104,11 @@ end it 'adds an event to processor context if waf status is :match' do - expect(Datadog::AppSec.active_context.processor_context).to( - receive(:run).and_return(instance_double(Datadog::AppSec::WAF::Result, status: :match, actions: {})) + expect(Datadog::AppSec.active_context).to( + receive(:run_rasp).and_return(instance_double(Datadog::AppSec::WAF::Result, status: :match, actions: {})) ) - expect(Datadog::AppSec.active_context.processor_context.events).to receive(:<<).and_call_original + expect(Datadog::AppSec.active_context.waf_runner.events).to receive(:<<).and_call_original User.where(name: 'Bob').to_a end diff --git a/spec/datadog/appsec/contrib/active_record/sqlite3_adapter_spec.rb b/spec/datadog/appsec/contrib/active_record/sqlite3_adapter_spec.rb index 9be5d7ebfad..c15246f9017 100644 --- a/spec/datadog/appsec/contrib/active_record/sqlite3_adapter_spec.rb +++ b/spec/datadog/appsec/contrib/active_record/sqlite3_adapter_spec.rb @@ -15,7 +15,7 @@ let(:telemetry) { instance_double(Datadog::Core::Telemetry::Component) } let(:ruleset) { Datadog::AppSec::Processor::RuleLoader.load_rules(ruleset: :recommended, telemetry: telemetry) } let(:processor) { Datadog::AppSec::Processor.new(ruleset: ruleset, telemetry: telemetry) } - let(:context) { processor.new_context } + let(:context) { Datadog::AppSec::Context.new(trace, span, processor) } let(:span) { Datadog::Tracing::SpanOperation.new('root') } let(:trace) { Datadog::Tracing::TraceOperation.new } @@ -37,10 +37,7 @@ end let(:db_config) do - { - adapter: 'sqlite3', - database: ':memory:' - } + { adapter: 'sqlite3', database: ':memory:' } end before do @@ -49,7 +46,7 @@ c.appsec.instrument :active_record end - Datadog::AppSec::Context.activate_context(trace, span, processor) + Datadog::AppSec::Context.activate(context) raise_on_rails_deprecation! end @@ -57,13 +54,14 @@ after do Datadog.configuration.reset! - Datadog::AppSec::Context.deactivate_context + Datadog::AppSec::Context.deactivate processor.finalize end it 'calls waf with correct arguments when querying using .where' do - expect(Datadog::AppSec.active_context.processor_context).to( - receive(:run).with( + expect(Datadog::AppSec.active_context).to( + receive(:run_rasp).with( + Datadog::AppSec::Ext::RASP_SQLI, {}, { 'server.db.statement' => 'SELECT "users".* FROM "users" WHERE "users"."name" = ?', @@ -77,8 +75,9 @@ end it 'calls waf with correct arguments when querying using .find_by_sql' do - expect(Datadog::AppSec.active_context.processor_context).to( - receive(:run).with( + expect(Datadog::AppSec.active_context).to( + receive(:run_rasp).with( + Datadog::AppSec::Ext::RASP_SQLI, {}, { 'server.db.statement' => "SELECT * FROM users WHERE name = 'Bob'", @@ -92,11 +91,11 @@ end it 'adds an event to processor context if waf status is :match' do - expect(Datadog::AppSec.active_context.processor_context).to( - receive(:run).and_return(instance_double(Datadog::AppSec::WAF::Result, status: :match, actions: {})) + expect(Datadog::AppSec.active_context).to( + receive(:run_rasp).and_return(instance_double(Datadog::AppSec::WAF::Result, status: :match, actions: {})) ) - expect(Datadog::AppSec.active_context.processor_context.events).to receive(:<<).and_call_original + expect(Datadog::AppSec.active_context.waf_runner.events).to receive(:<<).and_call_original User.where(name: 'Bob').to_a end diff --git a/spec/datadog/appsec/contrib/graphql/reactive/multiplex_spec.rb b/spec/datadog/appsec/contrib/graphql/reactive/multiplex_spec.rb index 21df7b7b6d5..36e3e9e020b 100644 --- a/spec/datadog/appsec/contrib/graphql/reactive/multiplex_spec.rb +++ b/spec/datadog/appsec/contrib/graphql/reactive/multiplex_spec.rb @@ -29,15 +29,15 @@ end describe '.subscribe' do - let(:waf_context) { double(:waf_context) } + let(:context) { instance_double(Datadog::AppSec::Context) } context 'not all addresses have been published' do it 'does not call the waf context' do expect(engine).to receive(:subscribe).with( 'graphql.server.all_resolvers' ).and_call_original - expect(waf_context).to_not receive(:run) - described_class.subscribe(engine, waf_context) + expect(context).to_not receive(:run) + described_class.subscribe(engine, context) end end @@ -46,12 +46,12 @@ expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :ok, timeout: false) - expect(waf_context).to receive(:run).with( + expect(context).to receive(:run).with( { 'graphql.server.all_resolvers' => expected_arguments }, {}, Datadog.configuration.appsec.waf_timeout ).and_return(waf_result) - described_class.subscribe(engine, waf_context) + described_class.subscribe(engine, context) gateway_multiplex = Datadog::AppSec::Contrib::GraphQL::Gateway::Multiplex.new(multiplex) result = described_class.publish(engine, gateway_multiplex) expect(result).to be_nil diff --git a/spec/datadog/appsec/contrib/rack/reactive/request_body_spec.rb b/spec/datadog/appsec/contrib/rack/reactive/request_body_spec.rb index 75cf9aae480..b5985d82889 100644 --- a/spec/datadog/appsec/contrib/rack/reactive/request_body_spec.rb +++ b/spec/datadog/appsec/contrib/rack/reactive/request_body_spec.rb @@ -28,13 +28,13 @@ end describe '.subscribe' do - let(:waf_context) { double(:waf_context) } + let(:context) { instance_double(Datadog::AppSec::Context) } context 'not all addresses have been published' do it 'does not call the waf context' do expect(engine).to receive(:subscribe).with('request.body').and_call_original - expect(waf_context).to_not receive(:run) - described_class.subscribe(engine, waf_context) + expect(context).to_not receive(:run) + described_class.subscribe(engine, context) end end @@ -45,12 +45,12 @@ expected_waf_arguments = { 'server.request.body' => { 'foo' => 'bar' } } waf_result = double(:waf_result, status: :ok, timeout: false) - expect(waf_context).to receive(:run).with( + expect(context).to receive(:run).with( expected_waf_arguments, {}, Datadog.configuration.appsec.waf_timeout ).and_return(waf_result) - described_class.subscribe(engine, waf_context) + described_class.subscribe(engine, context) result = described_class.publish(engine, request) expect(result).to be_nil end diff --git a/spec/datadog/appsec/contrib/rack/reactive/request_spec.rb b/spec/datadog/appsec/contrib/rack/reactive/request_spec.rb index f22a3964b1d..09793f707a6 100644 --- a/spec/datadog/appsec/contrib/rack/reactive/request_spec.rb +++ b/spec/datadog/appsec/contrib/rack/reactive/request_spec.rb @@ -47,7 +47,7 @@ end describe '.subscribe' do - let(:waf_context) { double(:waf_context) } + let(:context) { instance_double(Datadog::AppSec::Context) } context 'not all addresses have been published' do it 'does not call the waf context' do @@ -59,8 +59,8 @@ 'request.client_ip', 'server.request.method', ).and_call_original - expect(waf_context).to_not receive(:run) - described_class.subscribe(engine, waf_context) + expect(context).to_not receive(:run) + described_class.subscribe(engine, context) end end @@ -79,12 +79,12 @@ } waf_result = double(:waf_result, status: :ok, timeout: false) - expect(waf_context).to receive(:run).with( + expect(context).to receive(:run).with( expected_waf_arguments, {}, Datadog.configuration.appsec.waf_timeout ).and_return(waf_result) - described_class.subscribe(engine, waf_context) + described_class.subscribe(engine, context) result = described_class.publish(engine, request) expect(result).to be_nil end diff --git a/spec/datadog/appsec/contrib/rack/reactive/response_spec.rb b/spec/datadog/appsec/contrib/rack/reactive/response_spec.rb index 0d53e61464f..6304efc5edf 100644 --- a/spec/datadog/appsec/contrib/rack/reactive/response_spec.rb +++ b/spec/datadog/appsec/contrib/rack/reactive/response_spec.rb @@ -9,8 +9,7 @@ RSpec.describe Datadog::AppSec::Contrib::Rack::Reactive::Response do let(:engine) { Datadog::AppSec::Reactive::Engine.new } - let(:processor_context) { instance_double(Datadog::AppSec::Processor::Context) } - let(:context) { instance_double(Datadog::AppSec::Context, processor_context: processor_context) } + let(:context) { instance_double(Datadog::AppSec::Context) } let(:body) { ['Ok'] } let(:headers) { { 'content-type' => 'text/html', 'set-cookie' => 'foo' } } @@ -41,15 +40,13 @@ 'response.status', 'response.headers', ).and_call_original - expect(processor_context).to_not receive(:run) - described_class.subscribe(engine, processor_context) + expect(context).to_not receive(:run_waf) + described_class.subscribe(engine, context) end end context 'waf arguments' do - before do - expect(engine).to receive(:subscribe).and_call_original - end + before { expect(engine).to receive(:subscribe).and_call_original } let(:waf_result) { double(:waf_result, status: :ok, timeout: false) } @@ -68,13 +65,15 @@ end it 'does call the waf context with the right arguments' do - expect(processor_context).to receive(:run).with( + expect(context).to receive(:run_waf).with( expected_waf_arguments, {}, Datadog.configuration.appsec.waf_timeout ).and_return(waf_result) - described_class.subscribe(engine, processor_context) + + described_class.subscribe(engine, context) result = described_class.publish(engine, response) + expect(result).to be_nil end end @@ -82,7 +81,6 @@ it_behaves_like 'waf result' do let(:gateway) { response } - let(:waf_context) { processor_context } end end end diff --git a/spec/datadog/appsec/contrib/rails/reactive/action_spec.rb b/spec/datadog/appsec/contrib/rails/reactive/action_spec.rb index fad066ef7cf..e4e39d5af0c 100644 --- a/spec/datadog/appsec/contrib/rails/reactive/action_spec.rb +++ b/spec/datadog/appsec/contrib/rails/reactive/action_spec.rb @@ -35,13 +35,13 @@ end describe '.subscribe' do - let(:waf_context) { double(:waf_context) } + let(:context) { instance_double(Datadog::AppSec::Context) } context 'not all addresses have been published' do it 'does not call the waf context' do expect(engine).to receive(:subscribe).with('rails.request.body', 'rails.request.route_params').and_call_original - expect(waf_context).to_not receive(:run) - described_class.subscribe(engine, waf_context) + expect(context).to_not receive(:run_waf) + described_class.subscribe(engine, context) end end @@ -55,12 +55,12 @@ } waf_result = double(:waf_result, status: :ok, timeout: false) - expect(waf_context).to receive(:run).with( + expect(context).to receive(:run_waf).with( expected_waf_arguments, {}, Datadog.configuration.appsec.waf_timeout ).and_return(waf_result) - described_class.subscribe(engine, waf_context) + described_class.subscribe(engine, context) result = described_class.publish(engine, request) expect(result).to be_nil end diff --git a/spec/datadog/appsec/contrib/sinatra/reactive/routed_spec.rb b/spec/datadog/appsec/contrib/sinatra/reactive/routed_spec.rb index 690d1609ecb..27c8f2b24f9 100644 --- a/spec/datadog/appsec/contrib/sinatra/reactive/routed_spec.rb +++ b/spec/datadog/appsec/contrib/sinatra/reactive/routed_spec.rb @@ -30,13 +30,13 @@ end describe '.subscribe' do - let(:waf_context) { double(:waf_context) } + let(:context) { instance_double(Datadog::AppSec::Context) } context 'not all addresses have been published' do it 'does not call the waf context' do expect(engine).to receive(:subscribe).with('sinatra.request.route_params').and_call_original - expect(waf_context).to_not receive(:run) - described_class.subscribe(engine, waf_context) + expect(context).to_not receive(:run) + described_class.subscribe(engine, context) end end @@ -49,12 +49,12 @@ } waf_result = double(:waf_result, status: :ok, timeout: false) - expect(waf_context).to receive(:run).with( + expect(context).to receive(:run).with( expected_waf_arguments, {}, Datadog.configuration.appsec.waf_timeout ).and_return(waf_result) - described_class.subscribe(engine, waf_context) + described_class.subscribe(engine, context) result = described_class.publish(engine, [request, routed_params]) expect(result).to be_nil end diff --git a/spec/datadog/appsec/monitor/reactive/set_user_spec.rb b/spec/datadog/appsec/monitor/reactive/set_user_spec.rb index 5e5472f6b2a..aef9b2bcc96 100644 --- a/spec/datadog/appsec/monitor/reactive/set_user_spec.rb +++ b/spec/datadog/appsec/monitor/reactive/set_user_spec.rb @@ -18,13 +18,13 @@ end describe '.subscribe' do - let(:waf_context) { double(:waf_context) } + let(:context) { instance_double(Datadog::AppSec::Context) } context 'not all addresses have been published' do it 'does not call the waf context' do expect(engine).to receive(:subscribe).with('usr.id').and_call_original - expect(waf_context).to_not receive(:run) - described_class.subscribe(engine, waf_context) + expect(context).to_not receive(:run_waf) + described_class.subscribe(engine, context) end end @@ -35,12 +35,12 @@ expected_waf_persisted_data = { 'usr.id' => 1 } waf_result = double(:waf_result, status: :ok, timeout: false) - expect(waf_context).to receive(:run).with( + expect(context).to receive(:run_waf).with( expected_waf_persisted_data, {}, Datadog.configuration.appsec.waf_timeout ).and_return(waf_result) - described_class.subscribe(engine, waf_context) + described_class.subscribe(engine, context) result = described_class.publish(engine, user) expect(result).to be_nil end diff --git a/spec/datadog/appsec/reactive/shared_examples.rb b/spec/datadog/appsec/reactive/shared_examples.rb index 352ae336781..b2e29648be3 100644 --- a/spec/datadog/appsec/reactive/shared_examples.rb +++ b/spec/datadog/appsec/reactive/shared_examples.rb @@ -6,8 +6,8 @@ expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :match, timeout: false, actions: []) - expect(waf_context).to receive(:run).and_return(waf_result) - described_class.subscribe(engine, waf_context) do |result| + expect(context).to receive(:run_waf).and_return(waf_result) + described_class.subscribe(engine, context) do |result| expect(result).to eq(waf_result) end result = described_class.publish(engine, gateway) @@ -18,8 +18,8 @@ expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :match, timeout: false, actions: ['block']) - expect(waf_context).to receive(:run).and_return(waf_result) - described_class.subscribe(engine, waf_context) do |result| + expect(context).to receive(:run_waf).and_return(waf_result) + described_class.subscribe(engine, context) do |result| expect(result).to eq(waf_result) end block = described_class.publish(engine, gateway) @@ -32,8 +32,8 @@ expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :ok, timeout: false) - expect(waf_context).to receive(:run).and_return(waf_result) - expect { |b| described_class.subscribe(engine, waf_context, &b) }.not_to yield_control + expect(context).to receive(:run_waf).and_return(waf_result) + expect { |b| described_class.subscribe(engine, context, &b) }.not_to yield_control result = described_class.publish(engine, gateway) expect(result).to be_nil end @@ -44,8 +44,8 @@ expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :invalid_call, timeout: false) - expect(waf_context).to receive(:run).and_return(waf_result) - expect { |b| described_class.subscribe(engine, waf_context, &b) }.not_to yield_control + expect(context).to receive(:run_waf).and_return(waf_result) + expect { |b| described_class.subscribe(engine, context, &b) }.not_to yield_control result = described_class.publish(engine, gateway) expect(result).to be_nil end @@ -56,8 +56,8 @@ expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :invalid_rule, timeout: false) - expect(waf_context).to receive(:run).and_return(waf_result) - expect { |b| described_class.subscribe(engine, waf_context, &b) }.not_to yield_control + expect(context).to receive(:run_waf).and_return(waf_result) + expect { |b| described_class.subscribe(engine, context, &b) }.not_to yield_control result = described_class.publish(engine, gateway) expect(result).to be_nil end @@ -68,8 +68,8 @@ expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :invalid_flow, timeout: false) - expect(waf_context).to receive(:run).and_return(waf_result) - expect { |b| described_class.subscribe(engine, waf_context, &b) }.not_to yield_control + expect(context).to receive(:run_waf).and_return(waf_result) + expect { |b| described_class.subscribe(engine, context, &b) }.not_to yield_control result = described_class.publish(engine, gateway) expect(result).to be_nil end @@ -80,8 +80,8 @@ expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :no_rule, timeout: false) - expect(waf_context).to receive(:run).and_return(waf_result) - expect { |b| described_class.subscribe(engine, waf_context, &b) }.not_to yield_control + expect(context).to receive(:run_waf).and_return(waf_result) + expect { |b| described_class.subscribe(engine, context, &b) }.not_to yield_control result = described_class.publish(engine, gateway) expect(result).to be_nil end @@ -92,8 +92,8 @@ expect(engine).to receive(:subscribe).and_call_original waf_result = double(:waf_result, status: :foo, timeout: false) - expect(waf_context).to receive(:run).and_return(waf_result) - expect { |b| described_class.subscribe(engine, waf_context, &b) }.not_to yield_control + expect(context).to receive(:run_waf).and_return(waf_result) + expect { |b| described_class.subscribe(engine, context, &b) }.not_to yield_control result = described_class.publish(engine, gateway) expect(result).to be_nil end diff --git a/spec/datadog/kit/appsec/events_spec.rb b/spec/datadog/kit/appsec/events_spec.rb index 7f2ff40ab04..200ea4812d0 100644 --- a/spec/datadog/kit/appsec/events_spec.rb +++ b/spec/datadog/kit/appsec/events_spec.rb @@ -9,15 +9,16 @@ let(:trace_op) { Datadog::Tracing::TraceOperation.new } shared_context 'uses AppSec context' do - before { allow(Datadog::AppSec).to receive(:active_context).and_return(appsec_active_context) } + before do + allow(processor).to receive(:new_context).and_return(instance_double(Datadog::AppSec::Processor::Context)) + allow(Datadog::AppSec).to receive(:active_context).and_return(appsec_active_context) + end + + let(:processor) { instance_double(Datadog::AppSec::Processor) } let(:appsec_span) { trace_op.build_span('root') } context 'when is present' do - let(:appsec_active_context) do - processor = instance_double('Datadog::Appsec::Processor') - - Datadog::AppSec::Context.new(trace_op, appsec_span, processor) - end + let(:appsec_active_context) { Datadog::AppSec::Context.new(trace_op, appsec_span, processor) } it 'sets tags on AppSec span' do event