diff --git a/lib/datadog/appsec/processor.rb b/lib/datadog/appsec/processor.rb index 983b310021b..2d0c42d1f90 100644 --- a/lib/datadog/appsec/processor.rb +++ b/lib/datadog/appsec/processor.rb @@ -22,6 +22,15 @@ def run(input, timeout = WAF::LibDDWAF::DDWAF_RUN_TIMEOUT) start_ns = Core::Utils::Time.get_time(:nanosecond) + input.reject! do |_, v| + case v + when TrueClass, FalseClass + false + else + v.nil? ? true : v.empty? + end + end + _code, res = @context.run(input, timeout) stop_ns = Core::Utils::Time.get_time(:nanosecond) diff --git a/sig/datadog/appsec/processor.rbs b/sig/datadog/appsec/processor.rbs index 1938e5b4002..0f2be11a9b3 100644 --- a/sig/datadog/appsec/processor.rbs +++ b/sig/datadog/appsec/processor.rbs @@ -15,7 +15,7 @@ module Datadog @run_mutex: ::Thread::Mutex def initialize: (Processor processor) -> void - def run: (data input, ?::Integer timeout) -> WAF::Result + def run: (Hash[untyped, untyped] input, ?::Integer timeout) -> WAF::Result def extract_schema: () -> WAF::Result? def finalize: () -> void diff --git a/spec/datadog/appsec/processor_spec.rb b/spec/datadog/appsec/processor_spec.rb index 04c838d4dd1..596c6b7fa83 100644 --- a/spec/datadog/appsec/processor_spec.rb +++ b/spec/datadog/appsec/processor_spec.rb @@ -217,6 +217,80 @@ matches.map(&:actions) end + context 'clear key with empty values' do + it 'removes nil values' do + input = { + 'nil_value' => nil, + 'string_value' => 'hello' + } + expect(context.instance_variable_get(:@context)).to receive(:run).with( + { + 'string_value' => 'hello' + }, + timeout + ).and_call_original + + context.run(input, timeout) + end + + it 'do not removes boolean values' do + input = { + 'false_value' => false, + 'true_value' => true + } + expect(context.instance_variable_get(:@context)).to receive(:run).with( + input, timeout + ).and_call_original + + context.run(input, timeout) + end + + it 'removes empty string values' do + input = { + 'empty_string_value' => '', + 'string_value' => 'hello' + } + expect(context.instance_variable_get(:@context)).to receive(:run).with( + { + 'string_value' => 'hello' + }, + timeout + ).and_call_original + + context.run(input, timeout) + end + + it 'removes empty arrays values' do + input = { + 'empty_array' => [], + 'non_empty_array_value' => [1, 2], + } + expect(context.instance_variable_get(:@context)).to receive(:run).with( + { + 'non_empty_array_value' => [1, 2] + }, + timeout + ).and_call_original + + context.run(input, timeout) + end + + it 'removes empty hash values' do + input = { + 'empty_hash' => {}, + 'non_empty_hash_value' => { 'hello' => 'world' }, + } + expect(context.instance_variable_get(:@context)).to receive(:run).with( + { + 'non_empty_hash_value' => { 'hello' => 'world' } + }, + timeout + ).and_call_original + + context.run(input, timeout) + end + end + context 'no attack' do let(:input) { input_safe }