Skip to content

Commit 070743f

Browse files
authored
Merge 869d0eb into e743328
2 parents e743328 + 869d0eb commit 070743f

File tree

11 files changed

+158
-29
lines changed

11 files changed

+158
-29
lines changed

datadog.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Gem::Specification.new do |spec|
6565
spec.add_dependency 'datadog-ruby_core_source', '~> 3.4', '>= 3.4.1'
6666

6767
# Used by appsec
68-
spec.add_dependency 'libddwaf', '~> 1.24.1.1.0'
68+
spec.add_dependency 'libddwaf', '~> 1.24.1.2.0'
6969

7070
# When updating the version here, please also update the version in `libdatadog_extconf_helpers.rb`
7171
# (and yes we have a test for it)

lib/datadog/appsec/metrics/collector.rb

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,28 @@ module AppSec
55
module Metrics
66
# A class responsible for collecting WAF and RASP call metrics.
77
class Collector
8-
Store = Struct.new(:evals, :matches, :errors, :timeouts, :duration_ns, :duration_ext_ns, keyword_init: true)
8+
Store = Struct.new(
9+
:evals,
10+
:matches,
11+
:errors,
12+
:timeouts,
13+
:duration_ns,
14+
:duration_ext_ns,
15+
:input_truncated_count,
16+
keyword_init: true
17+
)
918

1019
attr_reader :waf, :rasp
1120

1221
def initialize
1322
@mutex = Mutex.new
14-
@waf = Store.new(evals: 0, matches: 0, errors: 0, timeouts: 0, duration_ns: 0, duration_ext_ns: 0)
15-
@rasp = Store.new(evals: 0, matches: 0, errors: 0, timeouts: 0, duration_ns: 0, duration_ext_ns: 0)
23+
24+
@waf = Store.new(
25+
evals: 0, matches: 0, errors: 0, timeouts: 0, duration_ns: 0, duration_ext_ns: 0, input_truncated_count: 0
26+
)
27+
@rasp = Store.new(
28+
evals: 0, matches: 0, errors: 0, timeouts: 0, duration_ns: 0, duration_ext_ns: 0, input_truncated_count: 0
29+
)
1630
end
1731

1832
def record_waf(result)
@@ -23,6 +37,7 @@ def record_waf(result)
2337
@waf.timeouts += 1 if result.timeout?
2438
@waf.duration_ns += result.duration_ns
2539
@waf.duration_ext_ns += result.duration_ext_ns
40+
@waf.input_truncated_count += 1 if result.input_truncated?
2641
end
2742
end
2843

@@ -34,6 +49,7 @@ def record_rasp(result)
3449
@rasp.timeouts += 1 if result.timeout?
3550
@rasp.duration_ns += result.duration_ns
3651
@rasp.duration_ext_ns += result.duration_ext_ns
52+
@rasp.input_truncated_count += 1 if result.input_truncated?
3753
end
3854
end
3955
end

lib/datadog/appsec/metrics/telemetry_exporter.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ def export_waf_request_metrics(metrics, context)
1818
waf_timeout: metrics.timeouts.positive?.to_s,
1919
request_blocked: context.interrupted?.to_s,
2020
block_failure: 'false',
21-
rate_limited: (!context.trace.sampled?).to_s
21+
rate_limited: (!context.trace.sampled?).to_s,
22+
input_truncated: metrics.input_truncated_count.positive?.to_s,
2223
}
2324
)
2425
end

lib/datadog/appsec/security_engine/result.rb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ module Result
99
class Base
1010
attr_reader :events, :actions, :derivatives, :duration_ns, :duration_ext_ns
1111

12-
def initialize(events:, actions:, derivatives:, timeout:, duration_ns:, duration_ext_ns:)
12+
def initialize(events:, actions:, derivatives:, timeout:, duration_ns:, duration_ext_ns:, input_truncated:)
1313
@events = events
1414
@actions = actions
1515
@derivatives = derivatives
1616

1717
@timeout = timeout
1818
@duration_ns = duration_ns
1919
@duration_ext_ns = duration_ext_ns
20+
@input_truncated = input_truncated
2021
end
2122

2223
def timeout?
@@ -30,6 +31,10 @@ def match?
3031
def error?
3132
raise NotImplementedError
3233
end
34+
35+
def input_truncated?
36+
@input_truncated
37+
end
3338
end
3439

3540
# A result that indicates a security rule match
@@ -58,11 +63,12 @@ def error?
5863
class Error
5964
attr_reader :events, :actions, :derivatives, :duration_ns, :duration_ext_ns
6065

61-
def initialize(duration_ext_ns:)
66+
def initialize(duration_ext_ns:, input_truncated:)
6267
@events = []
6368
@actions = @derivatives = {}
6469
@duration_ns = 0
6570
@duration_ext_ns = duration_ext_ns
71+
@input_truncated = input_truncated
6672
end
6773

6874
def timeout?
@@ -76,6 +82,10 @@ def match?
7682
def error?
7783
true
7884
end
85+
86+
def input_truncated?
87+
@input_truncated
88+
end
7989
end
8090
end
8191
end

lib/datadog/appsec/security_engine/runner.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def run(persistent_data, ephemeral_data, timeout = WAF::LibDDWAF::DDWAF_RUN_TIME
4242
report_execution(result)
4343

4444
unless SUCCESSFUL_EXECUTION_CODES.include?(result.status)
45-
return Result::Error.new(duration_ext_ns: stop_ns - start_ns)
45+
return Result::Error.new(duration_ext_ns: stop_ns - start_ns, input_truncated: result.input_truncated?)
4646
end
4747

4848
klass = (result.status == :match) ? Result::Match : Result::Ok
@@ -52,7 +52,8 @@ def run(persistent_data, ephemeral_data, timeout = WAF::LibDDWAF::DDWAF_RUN_TIME
5252
derivatives: result.derivatives,
5353
timeout: result.timeout,
5454
duration_ns: result.total_runtime,
55-
duration_ext_ns: (stop_ns - start_ns)
55+
duration_ext_ns: (stop_ns - start_ns),
56+
input_truncated: result.input_truncated?
5657
)
5758
ensure
5859
@mutex.unlock

sig/datadog/appsec/metrics/collector.rbs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ module Datadog
1515

1616
attr_accessor duration_ext_ns: ::Integer
1717

18-
def self.new: (evals: ::Integer, matches: ::Integer, errors: ::Integer, timeouts: ::Integer, duration_ns: ::Integer, duration_ext_ns: ::Integer) -> void
18+
attr_accessor input_truncated_count: ::Integer
19+
20+
def self.new: (evals: ::Integer, matches: ::Integer, errors: ::Integer, timeouts: ::Integer, duration_ns: ::Integer, duration_ext_ns: ::Integer, input_truncated_count: ::Integer) -> void
1921
end
2022

2123
@mutex: Mutex

sig/datadog/appsec/security_engine/result.rbs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ module Datadog
2121

2222
@duration_ext_ns: ::Integer
2323

24+
@input_truncated: bool
25+
2426
attr_reader events: events
2527

2628
attr_reader actions: actions
@@ -31,13 +33,15 @@ module Datadog
3133

3234
attr_reader duration_ext_ns: ::Integer
3335

34-
def initialize: (events: events, actions: actions, derivatives: derivatives, timeout: bool, duration_ns: ::Integer, duration_ext_ns: ::Integer) -> void
36+
def initialize: (events: events, actions: actions, derivatives: derivatives, timeout: bool, duration_ns: ::Integer, duration_ext_ns: ::Integer, input_truncated: bool) -> void
3537

3638
def timeout?: () -> bool
3739

3840
def match?: () -> bool
3941

4042
def error?: () -> bool
43+
44+
def input_truncated?: () -> bool
4145
end
4246

4347
# A result that indicates a security rule match
@@ -66,6 +70,8 @@ module Datadog
6670

6771
@duration_ext_ns: ::Integer
6872

73+
@input_truncated: bool
74+
6975
attr_reader events: events
7076

7177
attr_reader actions: actions
@@ -76,13 +82,15 @@ module Datadog
7682

7783
attr_reader duration_ext_ns: ::Integer
7884

79-
def initialize: (duration_ext_ns: ::Integer) -> void
85+
def initialize: (duration_ext_ns: ::Integer, input_truncated: bool) -> void
8086

8187
def timeout?: () -> false
8288

8389
def match?: () -> false
8490

8591
def error?: () -> true
92+
93+
def input_truncated?: () -> bool
8694
end
8795
end
8896
end

spec/datadog/appsec/metrics/collector_spec.rb

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
expect(collector.waf.timeouts).to eq(0)
1515
expect(collector.waf.duration_ns).to eq(0)
1616
expect(collector.waf.duration_ext_ns).to eq(0)
17+
expect(collector.waf.input_truncated_count).to eq(0)
1718
end
1819
end
1920

@@ -22,7 +23,8 @@
2223

2324
let(:result) do
2425
Datadog::AppSec::SecurityEngine::Result::Ok.new(
25-
events: [], actions: {}, derivatives: {}, timeout: false, duration_ns: 100, duration_ext_ns: 200
26+
events: [], actions: {}, derivatives: {}, timeout: false, duration_ns: 100,
27+
duration_ext_ns: 200, input_truncated: false
2628
)
2729
end
2830

@@ -33,6 +35,7 @@
3335
expect(collector.waf.timeouts).to eq(0)
3436
expect(collector.waf.duration_ns).to eq(100)
3537
expect(collector.waf.duration_ext_ns).to eq(200)
38+
expect(collector.waf.input_truncated_count).to eq(0)
3639
end
3740
end
3841

@@ -44,13 +47,15 @@
4447

4548
let(:result_1) do
4649
Datadog::AppSec::SecurityEngine::Result::Ok.new(
47-
events: [], actions: {}, derivatives: {}, timeout: false, duration_ns: 100, duration_ext_ns: 200
50+
events: [], actions: {}, derivatives: {}, timeout: false, duration_ns: 100,
51+
duration_ext_ns: 200, input_truncated: false
4852
)
4953
end
5054

5155
let(:result_2) do
5256
Datadog::AppSec::SecurityEngine::Result::Match.new(
53-
events: [], actions: {}, derivatives: {}, timeout: false, duration_ns: 1000, duration_ext_ns: 1200
57+
events: [], actions: {}, derivatives: {}, timeout: false, duration_ns: 1000,
58+
duration_ext_ns: 1200, input_truncated: false
5459
)
5560
end
5661

@@ -60,6 +65,7 @@
6065
expect(collector.waf.errors).to eq(0)
6166
expect(collector.waf.duration_ns).to eq(1100)
6267
expect(collector.waf.duration_ext_ns).to eq(1400)
68+
expect(collector.waf.input_truncated_count).to eq(0)
6369
end
6470
end
6571

@@ -72,17 +78,21 @@
7278

7379
let(:result_1) do
7480
Datadog::AppSec::SecurityEngine::Result::Ok.new(
75-
events: [], actions: {}, derivatives: {}, timeout: true, duration_ns: 100, duration_ext_ns: 500
81+
events: [], actions: {}, derivatives: {}, timeout: true, duration_ns: 100,
82+
duration_ext_ns: 500, input_truncated: false
7683
)
7784
end
7885

7986
let(:result_2) do
8087
Datadog::AppSec::SecurityEngine::Result::Match.new(
81-
events: [], actions: {}, derivatives: {}, timeout: true, duration_ns: 400, duration_ext_ns: 1200
88+
events: [], actions: {}, derivatives: {}, timeout: true, duration_ns: 400,
89+
duration_ext_ns: 1200, input_truncated: false
8290
)
8391
end
8492

85-
let(:result_3) { Datadog::AppSec::SecurityEngine::Result::Error.new(duration_ext_ns: 300) }
93+
let(:result_3) do
94+
Datadog::AppSec::SecurityEngine::Result::Error.new(duration_ext_ns: 300, input_truncated: false)
95+
end
8696

8797
it 'accumulates timeouts in addition to other metics' do
8898
expect(collector.waf.evals).to eq(3)
@@ -91,6 +101,7 @@
91101
expect(collector.waf.timeouts).to eq(2)
92102
expect(collector.waf.duration_ns).to eq(500)
93103
expect(collector.waf.duration_ext_ns).to eq(2000)
104+
expect(collector.waf.input_truncated_count).to eq(0)
94105
end
95106
end
96107
end
@@ -104,6 +115,7 @@
104115
expect(collector.rasp.timeouts).to eq(0)
105116
expect(collector.rasp.duration_ns).to eq(0)
106117
expect(collector.rasp.duration_ext_ns).to eq(0)
118+
expect(collector.rasp.input_truncated_count).to eq(0)
107119
end
108120
end
109121

@@ -112,7 +124,8 @@
112124

113125
let(:result) do
114126
Datadog::AppSec::SecurityEngine::Result::Ok.new(
115-
events: [], actions: {}, derivatives: {}, timeout: false, duration_ns: 100, duration_ext_ns: 200
127+
events: [], actions: {}, derivatives: {}, timeout: false, duration_ns: 100,
128+
duration_ext_ns: 200, input_truncated: false
116129
)
117130
end
118131

@@ -123,6 +136,7 @@
123136
expect(collector.rasp.timeouts).to eq(0)
124137
expect(collector.rasp.duration_ns).to eq(100)
125138
expect(collector.rasp.duration_ext_ns).to eq(200)
139+
expect(collector.rasp.input_truncated_count).to eq(0)
126140
end
127141
end
128142

@@ -134,13 +148,15 @@
134148

135149
let(:result_1) do
136150
Datadog::AppSec::SecurityEngine::Result::Ok.new(
137-
events: [], actions: {}, derivatives: {}, timeout: false, duration_ns: 100, duration_ext_ns: 200
151+
events: [], actions: {}, derivatives: {}, timeout: false, duration_ns: 100,
152+
duration_ext_ns: 200, input_truncated: false
138153
)
139154
end
140155

141156
let(:result_2) do
142157
Datadog::AppSec::SecurityEngine::Result::Match.new(
143-
events: [], actions: {}, derivatives: {}, timeout: false, duration_ns: 1000, duration_ext_ns: 1200
158+
events: [], actions: {}, derivatives: {}, timeout: false, duration_ns: 1000,
159+
duration_ext_ns: 1200, input_truncated: false
144160
)
145161
end
146162

@@ -151,6 +167,7 @@
151167
expect(collector.rasp.timeouts).to eq(0)
152168
expect(collector.rasp.duration_ns).to eq(1100)
153169
expect(collector.rasp.duration_ext_ns).to eq(1400)
170+
expect(collector.rasp.input_truncated_count).to eq(0)
154171
end
155172
end
156173

@@ -163,17 +180,22 @@
163180

164181
let(:result_1) do
165182
Datadog::AppSec::SecurityEngine::Result::Ok.new(
166-
events: [], actions: {}, derivatives: {}, timeout: true, duration_ns: 100, duration_ext_ns: 500
183+
events: [], actions: {}, derivatives: {}, timeout: true, duration_ns: 100,
184+
duration_ext_ns: 500, input_truncated: false
167185
)
168186
end
169187

170188
let(:result_2) do
171189
Datadog::AppSec::SecurityEngine::Result::Match.new(
172-
events: [], actions: {}, derivatives: {}, timeout: true, duration_ns: 400, duration_ext_ns: 1200
190+
events: [], actions: {}, derivatives: {}, timeout: true, duration_ns: 400,
191+
duration_ext_ns: 1200,
192+
input_truncated: false
173193
)
174194
end
175195

176-
let(:result_3) { Datadog::AppSec::SecurityEngine::Result::Error.new(duration_ext_ns: 300) }
196+
let(:result_3) do
197+
Datadog::AppSec::SecurityEngine::Result::Error.new(duration_ext_ns: 300, input_truncated: false)
198+
end
177199

178200
it 'accumulates timeouts in addition to other metics' do
179201
expect(collector.rasp.evals).to eq(3)
@@ -182,6 +204,7 @@
182204
expect(collector.rasp.timeouts).to eq(2)
183205
expect(collector.rasp.duration_ns).to eq(500)
184206
expect(collector.rasp.duration_ext_ns).to eq(2000)
207+
expect(collector.rasp.input_truncated_count).to eq(0)
185208
end
186209
end
187210
end

0 commit comments

Comments
 (0)