libddwaf 1.22.0.0.2-aarch64-linux → 1.24.1.0.3-aarch64-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -2
- data/README.md +124 -0
- data/lib/datadog/appsec/waf/context.rb +24 -38
- data/lib/datadog/appsec/waf/converter.rb +62 -69
- data/lib/datadog/appsec/waf/errors.rb +19 -0
- data/lib/datadog/appsec/waf/handle.rb +29 -77
- data/lib/datadog/appsec/waf/handle_builder.rb +91 -0
- data/lib/datadog/appsec/waf/lib_ddwaf.rb +90 -123
- data/lib/datadog/appsec/waf/version.rb +3 -3
- data/lib/datadog/appsec/waf.rb +9 -7
- data/lib/libddwaf.rb +1 -1
- data/libddwaf.gemspec +43 -0
- data/sig/datadog/appsec/waf/context.rbs +29 -0
- data/sig/datadog/appsec/waf/converter.rbs +11 -0
- data/sig/datadog/appsec/waf/errors.rbs +20 -0
- data/sig/datadog/appsec/waf/handle.rbs +21 -0
- data/sig/datadog/appsec/waf/handle_builder.rbs +23 -0
- data/sig/datadog/appsec/waf/lib_ddwaf.rbs +158 -0
- data/sig/datadog/appsec/waf/result.rbs +33 -0
- data/sig/datadog/appsec/waf/version.rbs +13 -0
- data/sig/datadog/appsec/waf.rbs +16 -0
- data/sig/libddwaf.rbs +0 -0
- data/vendor/libddwaf/{libddwaf-1.22.0-linux-aarch64 → libddwaf-1.24.1-linux-aarch64}/lib/libddwaf.so +0 -0
- data/vendor/rbs/gem/0/gem.rbs +7 -0
- data/vendor/rbs/jruby/0/jruby.rbs +3 -0
- metadata +19 -3
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module AppSec
|
5
|
+
module WAF
|
6
|
+
# This class represents the libddwaf WAF builder, which is used to generate WAF handles.
|
7
|
+
#
|
8
|
+
# It handles merging of potentially overlapping configurations.
|
9
|
+
class HandleBuilder
|
10
|
+
def initialize(limits: {}, obfuscator: {})
|
11
|
+
handle_config_obj = LibDDWAF::HandleBuilderConfig.new
|
12
|
+
if handle_config_obj.null?
|
13
|
+
raise LibDDWAFError, "Could not create config struct"
|
14
|
+
end
|
15
|
+
|
16
|
+
handle_config_obj[:limits][:max_container_size] = limits[:max_container_size] || LibDDWAF::DEFAULT_MAX_CONTAINER_SIZE
|
17
|
+
handle_config_obj[:limits][:max_container_depth] = limits[:max_container_depth] || LibDDWAF::DEFAULT_MAX_CONTAINER_DEPTH
|
18
|
+
handle_config_obj[:limits][:max_string_length] = limits[:max_string_length] || LibDDWAF::DEFAULT_MAX_STRING_LENGTH
|
19
|
+
|
20
|
+
handle_config_obj[:obfuscator][:key_regex] = FFI::MemoryPointer.from_string(obfuscator[:key_regex]) if obfuscator[:key_regex]
|
21
|
+
handle_config_obj[:obfuscator][:value_regex] = FFI::MemoryPointer.from_string(obfuscator[:value_regex]) if obfuscator[:value_regex]
|
22
|
+
handle_config_obj[:free_fn] = LibDDWAF::ObjectNoFree
|
23
|
+
|
24
|
+
@builder_ptr = LibDDWAF.ddwaf_builder_init(handle_config_obj)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Destroys the WAF builder and sets the pointer to nil.
|
28
|
+
#
|
29
|
+
# The instance becomes unusable after this method is called.
|
30
|
+
def finalize!
|
31
|
+
builder_ptr_to_destroy = @builder_ptr
|
32
|
+
@builder_ptr = nil
|
33
|
+
|
34
|
+
LibDDWAF.ddwaf_builder_destroy(builder_ptr_to_destroy)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Builds a WAF handle from the current state of the builder.
|
38
|
+
#
|
39
|
+
# @raise [LibDDWAFError] if no rules were added to the builder before building the handle
|
40
|
+
# @return [Handle] the WAF handle
|
41
|
+
def build_handle
|
42
|
+
ensure_pointer_presence!
|
43
|
+
|
44
|
+
handle_obj = LibDDWAF.ddwaf_builder_build_instance(@builder_ptr)
|
45
|
+
raise LibDDWAFError, "Could not create handle" if handle_obj.null?
|
46
|
+
|
47
|
+
Handle.new(handle_obj)
|
48
|
+
end
|
49
|
+
|
50
|
+
# :section: Configuration management methods
|
51
|
+
# methods for adding, updating, and removing configurations from the WAF handle builder.
|
52
|
+
|
53
|
+
# Adds or updates a configuration in the WAF handle builder for the given path.
|
54
|
+
#
|
55
|
+
# @return [Hash] diagnostics object
|
56
|
+
# NOTE: default config that was read from file at application startup
|
57
|
+
# has to be removed before adding configurations obtained through Remote Configuration.
|
58
|
+
def add_or_update_config(config, path:)
|
59
|
+
ensure_pointer_presence!
|
60
|
+
|
61
|
+
config_obj = Converter.ruby_to_object(config)
|
62
|
+
diagnostics_obj = LibDDWAF::Object.new
|
63
|
+
|
64
|
+
LibDDWAF.ddwaf_builder_add_or_update_config(@builder_ptr, path, path.length, config_obj, diagnostics_obj)
|
65
|
+
|
66
|
+
Converter.object_to_ruby(diagnostics_obj)
|
67
|
+
ensure
|
68
|
+
LibDDWAF.ddwaf_object_free(config_obj) if config_obj
|
69
|
+
LibDDWAF.ddwaf_object_free(diagnostics_obj) if diagnostics_obj
|
70
|
+
end
|
71
|
+
|
72
|
+
# Removes a configuration from the WAF handle builder for the given path.
|
73
|
+
#
|
74
|
+
# @return [Boolean] true if the configuration was removed, false otherwise
|
75
|
+
def remove_config_at_path(path)
|
76
|
+
ensure_pointer_presence!
|
77
|
+
|
78
|
+
LibDDWAF.ddwaf_builder_remove_config(@builder_ptr, path, path.length)
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def ensure_pointer_presence!
|
84
|
+
return if @builder_ptr
|
85
|
+
|
86
|
+
raise InstanceFinalizedError, "Cannot use WAF handle builder after it has been finalized"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "ffi"
|
4
|
+
require "datadog/appsec/waf/version"
|
5
5
|
|
6
6
|
module Datadog
|
7
7
|
module AppSec
|
@@ -9,28 +9,27 @@ module Datadog
|
|
9
9
|
# FFI-binding for C-libddwaf
|
10
10
|
# See https://github.com/DataDog/libddwaf
|
11
11
|
module LibDDWAF
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
DEFAULT_MAX_CONTAINER_SIZE = 256
|
13
|
+
DEFAULT_MAX_CONTAINER_DEPTH = 20
|
14
|
+
DEFAULT_MAX_STRING_LENGTH = 16_384 # in bytes, UTF-8 worst case being 4x size in terms of code point
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
DDWAF_MAX_CONTAINER_SIZE = 256
|
17
|
+
DDWAF_MAX_CONTAINER_DEPTH = 20
|
18
|
+
DDWAF_MAX_STRING_LENGTH = 4096
|
18
19
|
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|
20
|
+
DDWAF_RUN_TIMEOUT = 5000
|
22
21
|
|
23
22
|
extend ::FFI::Library
|
24
23
|
|
25
24
|
def self.local_os
|
26
|
-
if RUBY_ENGINE ==
|
27
|
-
os_name = java.lang.System.get_property(
|
25
|
+
if RUBY_ENGINE == "jruby"
|
26
|
+
os_name = java.lang.System.get_property("os.name")
|
28
27
|
|
29
28
|
os = case os_name
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
when /linux/i then "linux"
|
30
|
+
when /mac/i then "darwin"
|
31
|
+
else raise Error, "unsupported JRuby os.name: #{os_name.inspect}"
|
32
|
+
end
|
34
33
|
|
35
34
|
return os
|
36
35
|
end
|
@@ -38,24 +37,15 @@ module Datadog
|
|
38
37
|
Gem::Platform.local.os
|
39
38
|
end
|
40
39
|
|
41
|
-
def self.local_version
|
42
|
-
return nil unless local_os == 'linux'
|
43
|
-
|
44
|
-
# Old rubygems don't handle non-gnu linux correctly
|
45
|
-
return ::Regexp.last_match(1) if RUBY_PLATFORM =~ /linux-(.+)$/
|
46
|
-
|
47
|
-
'gnu'
|
48
|
-
end
|
49
|
-
|
50
40
|
def self.local_cpu
|
51
|
-
if RUBY_ENGINE ==
|
52
|
-
os_arch = java.lang.System.get_property(
|
41
|
+
if RUBY_ENGINE == "jruby"
|
42
|
+
os_arch = java.lang.System.get_property("os.arch")
|
53
43
|
|
54
44
|
cpu = case os_arch
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
45
|
+
when "amd64" then "x86_64"
|
46
|
+
when "aarch64" then (local_os == "darwin") ? "arm64" : "aarch64"
|
47
|
+
else raise Error, "unsupported JRuby os.arch: #{os_arch.inspect}"
|
48
|
+
end
|
59
49
|
|
60
50
|
return cpu
|
61
51
|
end
|
@@ -64,48 +54,24 @@ module Datadog
|
|
64
54
|
end
|
65
55
|
|
66
56
|
def self.source_dir
|
67
|
-
__dir__ || raise(
|
68
|
-
end
|
69
|
-
|
70
|
-
def self.vendor_dir
|
71
|
-
File.join(source_dir, '../../../../vendor')
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.libddwaf_vendor_dir
|
75
|
-
File.join(vendor_dir, 'libddwaf')
|
76
|
-
end
|
77
|
-
|
78
|
-
def self.shared_lib_triplet(version: local_version)
|
79
|
-
version ? "#{local_os}-#{version}-#{local_cpu}" : "#{local_os}-#{local_cpu}"
|
80
|
-
end
|
81
|
-
|
82
|
-
def self.libddwaf_dir
|
83
|
-
default = File.join(libddwaf_vendor_dir,
|
84
|
-
"libddwaf-#{Datadog::AppSec::WAF::VERSION::BASE_STRING}-#{shared_lib_triplet}")
|
85
|
-
candidates = [
|
86
|
-
default
|
87
|
-
]
|
88
|
-
|
89
|
-
if local_os == 'linux'
|
90
|
-
candidates << File.join(libddwaf_vendor_dir,
|
91
|
-
"libddwaf-#{Datadog::AppSec::WAF::VERSION::BASE_STRING}-#{shared_lib_triplet(version: nil)}")
|
92
|
-
end
|
93
|
-
|
94
|
-
candidates.find { |d| Dir.exist?(d) } || default
|
57
|
+
__dir__ || raise("__dir__ is nil: eval?")
|
95
58
|
end
|
96
59
|
|
97
60
|
def self.shared_lib_extname
|
98
|
-
if Gem::Platform.local.os ==
|
99
|
-
|
100
|
-
elsif Gem::Platform.local.os ==
|
101
|
-
|
61
|
+
if Gem::Platform.local.os == "darwin"
|
62
|
+
".dylib"
|
63
|
+
elsif Gem::Platform.local.os == "java" && java.lang.System.get_property("os.name").match(/mac/i)
|
64
|
+
".dylib"
|
102
65
|
else
|
103
|
-
|
66
|
+
".so"
|
104
67
|
end
|
105
68
|
end
|
106
69
|
|
107
70
|
def self.shared_lib_path
|
108
|
-
|
71
|
+
variant = "#{Datadog::AppSec::WAF::VERSION::BASE_STRING}-#{local_os}-#{local_cpu}"
|
72
|
+
libddwaf_dir = File.join(source_dir, "../../../../vendor/libddwaf/libddwaf-#{variant}")
|
73
|
+
|
74
|
+
File.join(libddwaf_dir, "lib", "libddwaf#{shared_lib_extname}")
|
109
75
|
end
|
110
76
|
|
111
77
|
ffi_lib [shared_lib_path]
|
@@ -116,15 +82,15 @@ module Datadog
|
|
116
82
|
|
117
83
|
# ddwaf::object data structure
|
118
84
|
|
119
|
-
DDWAF_OBJ_TYPE = enum :ddwaf_obj_invalid,
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
85
|
+
DDWAF_OBJ_TYPE = enum :ddwaf_obj_invalid, 0,
|
86
|
+
:ddwaf_obj_signed, 1 << 0,
|
87
|
+
:ddwaf_obj_unsigned, 1 << 1,
|
88
|
+
:ddwaf_obj_string, 1 << 2,
|
89
|
+
:ddwaf_obj_array, 1 << 3,
|
90
|
+
:ddwaf_obj_map, 1 << 4,
|
91
|
+
:ddwaf_obj_bool, 1 << 5,
|
92
|
+
:ddwaf_obj_float, 1 << 6,
|
93
|
+
:ddwaf_obj_null, 1 << 7
|
128
94
|
|
129
95
|
typedef DDWAF_OBJ_TYPE, :ddwaf_obj_type
|
130
96
|
|
@@ -155,21 +121,21 @@ module Datadog
|
|
155
121
|
# Ruby representation of C union
|
156
122
|
class ObjectValueUnion < ::FFI::Union
|
157
123
|
layout :stringValue, :charptr,
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
124
|
+
:uintValue, :uint64,
|
125
|
+
:intValue, :int64,
|
126
|
+
:array, :pointer,
|
127
|
+
:boolean, :bool,
|
128
|
+
:f64, :double
|
163
129
|
end
|
164
130
|
|
165
131
|
# Ruby representation of ddwaf_object
|
166
132
|
# See https://github.com/DataDog/libddwaf/blob/10e3a1dfc7bc9bb8ab11a09a9f8b6b339eaf3271/include/ddwaf.h#L94C1-L115C3
|
167
133
|
class Object < ::FFI::Struct
|
168
|
-
layout :parameterName,
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
134
|
+
layout :parameterName, :charptr,
|
135
|
+
:parameterNameLength, :uint64,
|
136
|
+
:valueUnion, ObjectValueUnion,
|
137
|
+
:nbEntries, :uint64,
|
138
|
+
:type, :ddwaf_obj_type
|
173
139
|
end
|
174
140
|
|
175
141
|
typedef Object.by_ref, :ddwaf_object
|
@@ -214,51 +180,62 @@ module Datadog
|
|
214
180
|
ObjectFree = attach_function :ddwaf_object_free, [:ddwaf_object], :void
|
215
181
|
ObjectNoFree = ::FFI::Pointer::NULL
|
216
182
|
|
217
|
-
#
|
183
|
+
# handle builder
|
218
184
|
|
185
|
+
typedef :pointer, :ddwaf_builder
|
219
186
|
typedef :pointer, :ddwaf_handle
|
220
|
-
typedef
|
187
|
+
typedef :pointer, :ddwaf_diagnostics
|
221
188
|
|
222
189
|
callback :ddwaf_object_free_fn, [:ddwaf_object], :void
|
223
190
|
|
224
191
|
# Ruby representation of ddwaf_config
|
225
192
|
# https://github.com/DataDog/libddwaf/blob/10e3a1dfc7bc9bb8ab11a09a9f8b6b339eaf3271/include/ddwaf.h#L129-L152
|
226
|
-
class
|
193
|
+
class HandleBuilderConfig < ::FFI::Struct
|
227
194
|
# Ruby representation of ddwaf_config_limits
|
228
195
|
# https://github.com/DataDog/libddwaf/blob/10e3a1dfc7bc9bb8ab11a09a9f8b6b339eaf3271/include/ddwaf.h#L131-L138
|
229
196
|
class Limits < ::FFI::Struct
|
230
|
-
layout :max_container_size,
|
231
|
-
|
232
|
-
|
197
|
+
layout :max_container_size, :uint32,
|
198
|
+
:max_container_depth, :uint32,
|
199
|
+
:max_string_length, :uint32
|
233
200
|
end
|
234
201
|
|
235
202
|
# Ruby representation of ddwaf_config_obfuscator
|
236
203
|
# https://github.com/DataDog/libddwaf/blob/10e3a1dfc7bc9bb8ab11a09a9f8b6b339eaf3271/include/ddwaf.h#L141-L146
|
237
204
|
class Obfuscator < ::FFI::Struct
|
238
|
-
layout :key_regex,
|
239
|
-
|
205
|
+
layout :key_regex, :pointer, # should be :charptr
|
206
|
+
:value_regex, :pointer # should be :charptr
|
240
207
|
end
|
241
208
|
|
242
|
-
layout :limits,
|
243
|
-
|
244
|
-
|
209
|
+
layout :limits, Limits,
|
210
|
+
:obfuscator, Obfuscator,
|
211
|
+
:free_fn, :pointer # :ddwaf_object_free_fn
|
245
212
|
end
|
246
213
|
|
247
|
-
typedef
|
214
|
+
typedef HandleBuilderConfig.by_ref, :ddwaf_config
|
215
|
+
|
216
|
+
attach_function :ddwaf_builder_init, [:ddwaf_config], :ddwaf_builder
|
217
|
+
attach_function :ddwaf_builder_destroy, [:ddwaf_builder], :void
|
218
|
+
|
219
|
+
attach_function :ddwaf_builder_add_or_update_config, [:ddwaf_builder, :string, :size_t, :ddwaf_object, :ddwaf_diagnostics], :bool
|
220
|
+
attach_function :ddwaf_builder_remove_config, [:ddwaf_builder, :string, :size_t], :bool
|
221
|
+
|
222
|
+
attach_function :ddwaf_builder_build_instance, [:ddwaf_builder], :ddwaf_handle
|
223
|
+
|
224
|
+
# handle
|
225
|
+
|
226
|
+
callback :ddwaf_object_free_fn, [:ddwaf_object], :void
|
248
227
|
|
249
|
-
attach_function :ddwaf_init, [:ddwaf_rule, :ddwaf_config, :ddwaf_object], :ddwaf_handle
|
250
|
-
attach_function :ddwaf_update, [:ddwaf_handle, :ddwaf_object, :ddwaf_object], :ddwaf_handle
|
251
228
|
attach_function :ddwaf_destroy, [:ddwaf_handle], :void
|
252
229
|
|
253
230
|
attach_function :ddwaf_known_addresses, [:ddwaf_handle, UInt32Ptr], :charptrptr
|
254
231
|
|
255
232
|
# updating
|
256
233
|
|
257
|
-
DDWAF_RET_CODE = enum :ddwaf_err_internal,
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
234
|
+
DDWAF_RET_CODE = enum :ddwaf_err_internal, -3,
|
235
|
+
:ddwaf_err_invalid_object, -2,
|
236
|
+
:ddwaf_err_invalid_argument, -1,
|
237
|
+
:ddwaf_ok, 0,
|
238
|
+
:ddwaf_match, 1
|
262
239
|
typedef DDWAF_RET_CODE, :ddwaf_ret_code
|
263
240
|
|
264
241
|
# running
|
@@ -271,11 +248,11 @@ module Datadog
|
|
271
248
|
# Ruby representation of ddwaf_result
|
272
249
|
# See https://github.com/DataDog/libddwaf/blob/10e3a1dfc7bc9bb8ab11a09a9f8b6b339eaf3271/include/ddwaf.h#L154-L173
|
273
250
|
class Result < ::FFI::Struct
|
274
|
-
layout :timeout,
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
251
|
+
layout :timeout, :bool,
|
252
|
+
:events, Object,
|
253
|
+
:actions, Object,
|
254
|
+
:derivatives, Object,
|
255
|
+
:total_runtime, :uint64
|
279
256
|
end
|
280
257
|
|
281
258
|
typedef Result.by_ref, :ddwaf_result
|
@@ -287,26 +264,16 @@ module Datadog
|
|
287
264
|
# logging
|
288
265
|
|
289
266
|
DDWAF_LOG_LEVEL = enum :ddwaf_log_trace,
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
267
|
+
:ddwaf_log_debug,
|
268
|
+
:ddwaf_log_info,
|
269
|
+
:ddwaf_log_warn,
|
270
|
+
:ddwaf_log_error,
|
271
|
+
:ddwaf_log_off
|
295
272
|
typedef DDWAF_LOG_LEVEL, :ddwaf_log_level
|
296
273
|
|
297
274
|
callback :ddwaf_log_cb, [:ddwaf_log_level, :string, :string, :uint, :charptr, :uint64], :void
|
298
275
|
|
299
276
|
attach_function :ddwaf_set_log_cb, [:ddwaf_log_cb, :ddwaf_log_level], :bool
|
300
|
-
|
301
|
-
DEFAULT_MAX_CONTAINER_SIZE = 256
|
302
|
-
DEFAULT_MAX_CONTAINER_DEPTH = 20
|
303
|
-
DEFAULT_MAX_STRING_LENGTH = 16_384 # in bytes, UTF-8 worst case being 4x size in terms of code point)
|
304
|
-
|
305
|
-
DDWAF_MAX_CONTAINER_SIZE = 256
|
306
|
-
DDWAF_MAX_CONTAINER_DEPTH = 20
|
307
|
-
DDWAF_MAX_STRING_LENGTH = 4096
|
308
|
-
|
309
|
-
DDWAF_RUN_TIMEOUT = 5000
|
310
277
|
end
|
311
278
|
end
|
312
279
|
end
|
@@ -2,11 +2,11 @@ module Datadog
|
|
2
2
|
module AppSec
|
3
3
|
module WAF
|
4
4
|
module VERSION
|
5
|
-
BASE_STRING =
|
5
|
+
BASE_STRING = "1.24.1"
|
6
6
|
# NOTE: Every change to the `BASE_STRING` should be accompanied
|
7
7
|
# by a reset of the patch version in the `STRING` below.
|
8
|
-
STRING = "#{BASE_STRING}.0.
|
9
|
-
MINIMUM_RUBY_VERSION =
|
8
|
+
STRING = "#{BASE_STRING}.0.3"
|
9
|
+
MINIMUM_RUBY_VERSION = "2.5"
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
data/lib/datadog/appsec/waf.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
3
|
+
require "datadog/appsec/waf/lib_ddwaf"
|
4
|
+
|
5
|
+
require "datadog/appsec/waf/handle_builder"
|
6
|
+
require "datadog/appsec/waf/handle"
|
7
|
+
require "datadog/appsec/waf/converter"
|
8
|
+
require "datadog/appsec/waf/errors"
|
9
|
+
require "datadog/appsec/waf/result"
|
10
|
+
require "datadog/appsec/waf/context"
|
11
|
+
require "datadog/appsec/waf/version"
|
10
12
|
|
11
13
|
module Datadog
|
12
14
|
module AppSec
|
data/lib/libddwaf.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require "datadog/appsec/waf"
|
data/libddwaf.gemspec
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "datadog/appsec/waf/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "libddwaf"
|
7
|
+
spec.version = Datadog::AppSec::WAF::VERSION::STRING
|
8
|
+
spec.required_ruby_version = [">= #{Datadog::AppSec::WAF::VERSION::MINIMUM_RUBY_VERSION}"]
|
9
|
+
spec.required_rubygems_version = ">= 2.0.0"
|
10
|
+
spec.authors = ["Datadog, Inc."]
|
11
|
+
spec.email = ["dev@datadoghq.com"]
|
12
|
+
|
13
|
+
spec.summary = "Datadog WAF"
|
14
|
+
spec.description = <<-EOS.gsub(/^[\s]+/, "")
|
15
|
+
libddwaf packages a WAF implementation in C++, exposed to Ruby
|
16
|
+
EOS
|
17
|
+
|
18
|
+
spec.homepage = "https://github.com/DataDog/libddwaf-rb"
|
19
|
+
spec.license = "BSD-3-Clause"
|
20
|
+
|
21
|
+
if spec.respond_to?(:metadata)
|
22
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
23
|
+
else
|
24
|
+
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
25
|
+
end
|
26
|
+
|
27
|
+
libddwaf_version = Datadog::AppSec::WAF::VERSION::BASE_STRING
|
28
|
+
|
29
|
+
spec.files = ["libddwaf.gemspec"]
|
30
|
+
spec.files.concat(Dir.glob("lib/**/*.rb"))
|
31
|
+
spec.files.concat(Dir.glob("{vendor/rbs,sig}/**/*.rbs"))
|
32
|
+
spec.files.concat(Dir.glob("{README,CHANGELOG,LICENSE,NOTICE}*"))
|
33
|
+
spec.files.concat(%W[
|
34
|
+
vendor/libddwaf/libddwaf-#{libddwaf_version}-darwin-arm64/lib/libddwaf.dylib
|
35
|
+
vendor/libddwaf/libddwaf-#{libddwaf_version}-darwin-x86_64/lib/libddwaf.dylib
|
36
|
+
vendor/libddwaf/libddwaf-#{libddwaf_version}-linux-aarch64/lib/libddwaf.so
|
37
|
+
vendor/libddwaf/libddwaf-#{libddwaf_version}-linux-x86_64/lib/libddwaf.so
|
38
|
+
])
|
39
|
+
|
40
|
+
spec.require_paths = ["lib"]
|
41
|
+
|
42
|
+
spec.add_dependency "ffi", "~> 1.0"
|
43
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Datadog
|
2
|
+
module AppSec
|
3
|
+
module WAF
|
4
|
+
class Context
|
5
|
+
@context_ptr: ::FFI::Pointer
|
6
|
+
|
7
|
+
@retained: Array[untyped]
|
8
|
+
|
9
|
+
RESULT_CODE: ::Hash[::Symbol, ::Symbol]
|
10
|
+
|
11
|
+
def initialize: (::FFI::Pointer context_ptr) -> void
|
12
|
+
|
13
|
+
def finalize!: () -> void
|
14
|
+
|
15
|
+
def run: (WAF::data persistent_data, WAF::data ephemeral_data, ?::Integer timeout) -> Result
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def ensure_pointer_presence!: () -> void
|
20
|
+
|
21
|
+
def retained: () -> Array[untyped]
|
22
|
+
|
23
|
+
def retain: (top object) -> void
|
24
|
+
|
25
|
+
def release: (top object) -> void
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Datadog
|
2
|
+
module AppSec
|
3
|
+
module WAF
|
4
|
+
module Converter
|
5
|
+
def self.ruby_to_object: (top val, ?max_container_size: ::Integer?, ?max_container_depth: ::Integer?, ?max_string_length: ::Integer?, ?coerce: bool?) -> LibDDWAF::Object
|
6
|
+
|
7
|
+
def self.object_to_ruby: (LibDDWAF::Object obj) -> WAF::data
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Datadog
|
2
|
+
module AppSec
|
3
|
+
module WAF
|
4
|
+
class Error < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
class InstanceFinalizedError < Error
|
8
|
+
end
|
9
|
+
|
10
|
+
class ConversionError < Error
|
11
|
+
end
|
12
|
+
|
13
|
+
class LibDDWAFError < Error
|
14
|
+
attr_reader diagnostics: WAF::data
|
15
|
+
|
16
|
+
def initialize: (::String msg, ?diagnostics: WAF::data?) -> void
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Datadog
|
2
|
+
module AppSec
|
3
|
+
module WAF
|
4
|
+
class Handle
|
5
|
+
@handle_ptr: ::FFI::Pointer
|
6
|
+
|
7
|
+
def initialize: (::FFI::Pointer handle_ptr) -> void
|
8
|
+
|
9
|
+
def finalize!: () -> void
|
10
|
+
|
11
|
+
def build_context: () -> Context
|
12
|
+
|
13
|
+
def known_addresses: () -> ::Array[::String?]
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def ensure_pointer_presence!: () -> void
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Datadog
|
2
|
+
module AppSec
|
3
|
+
module WAF
|
4
|
+
class HandleBuilder
|
5
|
+
@builder_ptr: ::FFI::Pointer
|
6
|
+
|
7
|
+
def initialize: (?limits: ::Hash[::Symbol, ::Integer], ?obfuscator: ::Hash[::Symbol, ::String]) -> void
|
8
|
+
|
9
|
+
def finalize!: () -> void
|
10
|
+
|
11
|
+
def build_handle: () -> Handle
|
12
|
+
|
13
|
+
def add_or_update_config: (data config, path: ::String) -> data
|
14
|
+
|
15
|
+
def remove_config_at_path: (::String path) -> bool
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def ensure_pointer_presence!: () -> void
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|