Skip to content

Commit 849baad

Browse files
authored
Merge pull request #4536 from DataDog/add-passlist-and-denylist-integration-rack-tests
[NO-TICKET] Add Rack integration tests with deny/pass list
2 parents e54dfda + 7dc9766 commit 849baad

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# frozen_string_literal: true
2+
3+
require 'datadog/tracing/contrib/support/spec_helper'
4+
require 'datadog/appsec/spec_helper'
5+
require 'rack/test'
6+
7+
require 'rack/contrib'
8+
require 'datadog/tracing'
9+
require 'datadog/appsec'
10+
11+
RSpec.describe 'Rack-request headers collection for identity.set_user' do
12+
include Rack::Test::Methods
13+
14+
before do
15+
Datadog.configure do |c|
16+
c.tracing.enabled = true
17+
18+
c.appsec.enabled = true
19+
c.appsec.instrument :rack
20+
21+
c.appsec.standalone.enabled = false
22+
c.appsec.waf_timeout = 10_000_000 # in us
23+
c.appsec.ip_passlist = []
24+
c.appsec.ip_denylist = []
25+
c.appsec.user_id_denylist = []
26+
c.appsec.ruleset = sqli_blocking_ruleset
27+
c.appsec.api_security.enabled = false
28+
c.appsec.api_security.sample_rate = 0.0
29+
30+
c.remote.enabled = false
31+
end
32+
33+
# NOTE: Don't reach the agent in any way
34+
allow_any_instance_of(Datadog::Tracing::Transport::HTTP::Client).to receive(:send_request)
35+
allow_any_instance_of(Datadog::Tracing::Transport::Traces::Transport).to receive(:native_events_supported?)
36+
.and_return(true)
37+
end
38+
39+
after do
40+
Datadog.configuration.reset!
41+
Datadog.registry[:rack].reset_configuration!
42+
end
43+
44+
let(:sqli_blocking_ruleset) do
45+
{
46+
'version' => '2.2',
47+
'metadata' => { 'rules_version' => '1.4.1' },
48+
'rules' => [
49+
{
50+
'id' => 'crs-942-100',
51+
'name' => 'SQL Injection Attack Detected via libinjection',
52+
'tags' => { 'type' => 'sql_injection', 'category' => 'attack_attempt' },
53+
'conditions' => [
54+
{
55+
'parameters' => {
56+
'inputs' => [
57+
{ 'address' => 'server.request.query' },
58+
{ 'address' => 'server.request.body' },
59+
{ 'address' => 'server.request.path_params' },
60+
{ 'address' => 'grpc.server.request.message' }
61+
]
62+
},
63+
'operator' => 'is_sqli'
64+
}
65+
],
66+
'transformers' => ['removeNulls'],
67+
'on_match' => ['block']
68+
},
69+
]
70+
}
71+
end
72+
73+
let(:app) do
74+
stack = Rack::Builder.new do
75+
use Datadog::Tracing::Contrib::Rack::TraceMiddleware
76+
use Datadog::AppSec::Contrib::Rack::RequestMiddleware
77+
78+
use Rack::JSONBodyParser
79+
use Datadog::AppSec::Contrib::Rack::RequestBodyMiddleware
80+
81+
map '/test' do
82+
run ->(_) { [200, { 'Content-Type' => 'text/html' }, ['OK']] }
83+
end
84+
end
85+
86+
stack.to_app
87+
end
88+
89+
subject(:response) { last_response }
90+
91+
context 'when deny and pass lists are not set' do
92+
before { get('/test', { q: '1 OR 1;' }, { 'HTTP_X_FORWARDED_FOR' => '1.2.3.4' }) }
93+
94+
it { expect(response).to be_forbidden }
95+
end
96+
97+
context 'when deny and pass lists are set' do
98+
before do
99+
Datadog.configure do |c|
100+
c.appsec.ip_denylist = ['1.2.3.4']
101+
c.appsec.ip_passlist = ['1.2.3.4']
102+
end
103+
104+
get('/test', { q: '1 OR 1;' }, { 'HTTP_X_FORWARDED_FOR' => '1.2.3.4' })
105+
end
106+
107+
it { expect(response).to be_ok }
108+
end
109+
110+
context 'when pass list is set' do
111+
before do
112+
Datadog.configure { |c| c.appsec.ip_passlist = ['1.2.3.4'] }
113+
114+
get('/test', { q: '1 OR 1;' }, { 'HTTP_X_FORWARDED_FOR' => '1.2.3.4' })
115+
end
116+
117+
it { expect(response).to be_ok }
118+
end
119+
120+
context 'when deny and pass lists are set and body contains SQLi' do
121+
before do
122+
Datadog.configure do |c|
123+
c.appsec.ip_denylist = ['1.2.3.4']
124+
c.appsec.ip_passlist = ['1.2.3.4']
125+
end
126+
127+
body = { statement: <<~SQL }
128+
-- select count(*) from accounts where account_number is null
129+
select count(*) from payments where created_at >= '2025-03-01' and created_at < '2025-03-08'
130+
SQL
131+
132+
post('/test', body.to_json, { 'CONTENT_TYPE' => 'application/json', 'HTTP_X_FORWARDED_FOR' => '1.2.3.4' })
133+
end
134+
135+
it { expect(response).to be_ok }
136+
end
137+
end

0 commit comments

Comments
 (0)