ddtrace 1.6.0 → 1.7.0
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 +50 -1
- data/ext/ddtrace_profiling_loader/extconf.rb +1 -1
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +66 -6
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +51 -54
- data/ext/ddtrace_profiling_native_extension/collectors_stack.c +11 -13
- data/ext/ddtrace_profiling_native_extension/extconf.rb +1 -1
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +3 -2
- data/ext/ddtrace_profiling_native_extension/setup_signal_handler.c +96 -0
- data/ext/ddtrace_profiling_native_extension/setup_signal_handler.h +7 -0
- data/ext/ddtrace_profiling_native_extension/stack_recorder.c +70 -18
- data/ext/ddtrace_profiling_native_extension/stack_recorder.h +1 -0
- data/lib/datadog/appsec/assets/blocked.html +98 -3
- data/lib/datadog/appsec/assets/blocked.json +1 -0
- data/lib/datadog/appsec/assets/blocked.text +5 -0
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +35 -46
- data/lib/datadog/appsec/assets/waf_rules/risky.json +1 -1
- data/lib/datadog/appsec/assets/waf_rules/strict.json +46 -1
- data/lib/datadog/appsec/assets.rb +2 -2
- data/lib/datadog/appsec/configuration/settings.rb +6 -0
- data/lib/datadog/appsec/configuration.rb +4 -0
- data/lib/datadog/appsec/contrib/rack/reactive/request.rb +4 -8
- data/lib/datadog/appsec/contrib/rack/request.rb +17 -0
- data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +2 -2
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +2 -2
- data/lib/datadog/appsec/contrib/rails/patcher.rb +3 -6
- data/lib/datadog/appsec/contrib/sinatra/ext.rb +1 -0
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +11 -8
- data/lib/datadog/appsec/extensions.rb +10 -0
- data/lib/datadog/appsec/processor.rb +18 -0
- data/lib/datadog/appsec/response.rb +54 -0
- data/lib/datadog/core/runtime/ext.rb +1 -1
- data/lib/datadog/opentracer/distributed_headers.rb +5 -7
- data/lib/datadog/opentracer/rack_propagator.rb +0 -3
- data/lib/datadog/opentracer/text_map_propagator.rb +5 -7
- data/lib/datadog/profiling/collectors/cpu_and_wall_time.rb +10 -4
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +4 -0
- data/lib/datadog/profiling/collectors/old_stack.rb +7 -0
- data/lib/datadog/profiling/exporter.rb +5 -0
- data/lib/datadog/profiling/old_recorder.rb +8 -0
- data/lib/datadog/profiling/profiler.rb +7 -0
- data/lib/datadog/profiling/scheduler.rb +4 -7
- data/lib/datadog/profiling/stack_recorder.rb +22 -0
- data/lib/datadog/profiling/tasks/setup.rb +0 -7
- data/lib/datadog/tracing/contrib/delayed_job/plugin.rb +4 -0
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +2 -1
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +6 -12
- data/lib/datadog/tracing/contrib/grpc/distributed/fetcher.rb +27 -0
- data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +38 -0
- data/lib/datadog/tracing/contrib/grpc/patcher.rb +0 -2
- data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +32 -0
- data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +33 -0
- data/lib/datadog/tracing/contrib/kafka/consumer_event.rb +1 -0
- data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +1 -0
- data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +1 -0
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +2 -0
- data/lib/datadog/tracing/contrib/que/tracer.rb +2 -0
- data/lib/datadog/tracing/contrib/racecar/events/batch.rb +4 -1
- data/lib/datadog/tracing/contrib/racecar/events/message.rb +4 -1
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +2 -0
- data/lib/datadog/tracing/contrib/redis/instrumentation.rb +2 -0
- data/lib/datadog/tracing/contrib/redis/integration.rb +2 -1
- data/lib/datadog/tracing/contrib/redis/patcher.rb +2 -3
- data/lib/datadog/tracing/contrib/resque/resque_job.rb +2 -0
- data/lib/datadog/tracing/contrib/shoryuken/tracer.rb +2 -0
- data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +5 -0
- data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -0
- data/lib/datadog/tracing/contrib/sneakers/tracer.rb +2 -0
- data/lib/datadog/tracing/distributed/b3.rb +66 -0
- data/lib/datadog/tracing/distributed/b3_single.rb +66 -0
- data/lib/datadog/tracing/distributed/datadog.rb +153 -0
- data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +1 -0
- data/lib/datadog/tracing/distributed/fetcher.rb +30 -0
- data/lib/datadog/tracing/distributed/headers/ext.rb +18 -16
- data/lib/datadog/tracing/distributed/helpers.rb +7 -6
- data/lib/datadog/tracing/distributed/propagation.rb +127 -0
- data/lib/datadog/tracing/propagation/http.rb +3 -106
- data/lib/datadog/tracing/trace_segment.rb +1 -1
- data/lib/ddtrace/transport/trace_formatter.rb +2 -5
- data/lib/ddtrace/version.rb +1 -1
- metadata +19 -14
- data/lib/datadog/tracing/distributed/headers/b3.rb +0 -55
- data/lib/datadog/tracing/distributed/headers/b3_single.rb +0 -67
- data/lib/datadog/tracing/distributed/headers/datadog.rb +0 -144
- data/lib/datadog/tracing/distributed/headers/parser.rb +0 -37
- data/lib/datadog/tracing/distributed/metadata/b3.rb +0 -55
- data/lib/datadog/tracing/distributed/metadata/b3_single.rb +0 -66
- data/lib/datadog/tracing/distributed/metadata/datadog.rb +0 -73
- data/lib/datadog/tracing/distributed/metadata/parser.rb +0 -34
- data/lib/datadog/tracing/propagation/grpc.rb +0 -98
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"errors": [{"title": "You've been blocked", "detail": "Sorry, you cannot access this page. Please contact the customer service team. Security provided by Datadog."}]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "2.2",
|
|
3
3
|
"metadata": {
|
|
4
|
-
"rules_version": "1.4.
|
|
4
|
+
"rules_version": "1.4.2"
|
|
5
5
|
},
|
|
6
6
|
"rules": [
|
|
7
7
|
{
|
|
@@ -2853,51 +2853,6 @@
|
|
|
2853
2853
|
],
|
|
2854
2854
|
"transformers": []
|
|
2855
2855
|
},
|
|
2856
|
-
{
|
|
2857
|
-
"id": "crs-941-100",
|
|
2858
|
-
"name": "XSS Attack Detected via libinjection",
|
|
2859
|
-
"tags": {
|
|
2860
|
-
"type": "xss",
|
|
2861
|
-
"crs_id": "941100",
|
|
2862
|
-
"category": "attack_attempt"
|
|
2863
|
-
},
|
|
2864
|
-
"conditions": [
|
|
2865
|
-
{
|
|
2866
|
-
"parameters": {
|
|
2867
|
-
"inputs": [
|
|
2868
|
-
{
|
|
2869
|
-
"address": "server.request.headers.no_cookies",
|
|
2870
|
-
"key_path": [
|
|
2871
|
-
"user-agent"
|
|
2872
|
-
]
|
|
2873
|
-
},
|
|
2874
|
-
{
|
|
2875
|
-
"address": "server.request.headers.no_cookies",
|
|
2876
|
-
"key_path": [
|
|
2877
|
-
"referer"
|
|
2878
|
-
]
|
|
2879
|
-
},
|
|
2880
|
-
{
|
|
2881
|
-
"address": "server.request.query"
|
|
2882
|
-
},
|
|
2883
|
-
{
|
|
2884
|
-
"address": "server.request.body"
|
|
2885
|
-
},
|
|
2886
|
-
{
|
|
2887
|
-
"address": "server.request.path_params"
|
|
2888
|
-
},
|
|
2889
|
-
{
|
|
2890
|
-
"address": "grpc.server.request.message"
|
|
2891
|
-
}
|
|
2892
|
-
]
|
|
2893
|
-
},
|
|
2894
|
-
"operator": "is_xss"
|
|
2895
|
-
}
|
|
2896
|
-
],
|
|
2897
|
-
"transformers": [
|
|
2898
|
-
"removeNulls"
|
|
2899
|
-
]
|
|
2900
|
-
},
|
|
2901
2856
|
{
|
|
2902
2857
|
"id": "crs-941-110",
|
|
2903
2858
|
"name": "XSS Filter - Category 1: Script Tag Vector",
|
|
@@ -4363,6 +4318,40 @@
|
|
|
4363
4318
|
"keys_only"
|
|
4364
4319
|
]
|
|
4365
4320
|
},
|
|
4321
|
+
{
|
|
4322
|
+
"id": "dog-000-007",
|
|
4323
|
+
"name": "Server side template injection: Velocity & Freemarker",
|
|
4324
|
+
"tags": {
|
|
4325
|
+
"type": "java_code_injection",
|
|
4326
|
+
"category": "attack_attempt"
|
|
4327
|
+
},
|
|
4328
|
+
"conditions": [
|
|
4329
|
+
{
|
|
4330
|
+
"parameters": {
|
|
4331
|
+
"inputs": [
|
|
4332
|
+
{
|
|
4333
|
+
"address": "server.request.query"
|
|
4334
|
+
},
|
|
4335
|
+
{
|
|
4336
|
+
"address": "server.request.body"
|
|
4337
|
+
},
|
|
4338
|
+
{
|
|
4339
|
+
"address": "server.request.path_params"
|
|
4340
|
+
},
|
|
4341
|
+
{
|
|
4342
|
+
"address": "server.request.headers.no_cookies"
|
|
4343
|
+
},
|
|
4344
|
+
{
|
|
4345
|
+
"address": "grpc.server.request.message"
|
|
4346
|
+
}
|
|
4347
|
+
],
|
|
4348
|
+
"regex": "#(?:set|foreach|macro|parse|if)\\(.*\\)|<#assign.*>"
|
|
4349
|
+
},
|
|
4350
|
+
"operator": "match_regex"
|
|
4351
|
+
}
|
|
4352
|
+
],
|
|
4353
|
+
"transformers": []
|
|
4354
|
+
},
|
|
4366
4355
|
{
|
|
4367
4356
|
"id": "nfd-000-001",
|
|
4368
4357
|
"name": "Detect common directory discovery scans",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "2.2",
|
|
3
3
|
"metadata": {
|
|
4
|
-
"rules_version": "1.4.
|
|
4
|
+
"rules_version": "1.4.2"
|
|
5
5
|
},
|
|
6
6
|
"rules": [
|
|
7
7
|
{
|
|
@@ -855,6 +855,51 @@
|
|
|
855
855
|
],
|
|
856
856
|
"transformers": []
|
|
857
857
|
},
|
|
858
|
+
{
|
|
859
|
+
"id": "crs-941-100",
|
|
860
|
+
"name": "XSS Attack Detected via libinjection",
|
|
861
|
+
"tags": {
|
|
862
|
+
"type": "xss",
|
|
863
|
+
"crs_id": "941100",
|
|
864
|
+
"category": "attack_attempt"
|
|
865
|
+
},
|
|
866
|
+
"conditions": [
|
|
867
|
+
{
|
|
868
|
+
"parameters": {
|
|
869
|
+
"inputs": [
|
|
870
|
+
{
|
|
871
|
+
"address": "server.request.headers.no_cookies",
|
|
872
|
+
"key_path": [
|
|
873
|
+
"user-agent"
|
|
874
|
+
]
|
|
875
|
+
},
|
|
876
|
+
{
|
|
877
|
+
"address": "server.request.headers.no_cookies",
|
|
878
|
+
"key_path": [
|
|
879
|
+
"referer"
|
|
880
|
+
]
|
|
881
|
+
},
|
|
882
|
+
{
|
|
883
|
+
"address": "server.request.query"
|
|
884
|
+
},
|
|
885
|
+
{
|
|
886
|
+
"address": "server.request.body"
|
|
887
|
+
},
|
|
888
|
+
{
|
|
889
|
+
"address": "server.request.path_params"
|
|
890
|
+
},
|
|
891
|
+
{
|
|
892
|
+
"address": "grpc.server.request.message"
|
|
893
|
+
}
|
|
894
|
+
]
|
|
895
|
+
},
|
|
896
|
+
"operator": "is_xss"
|
|
897
|
+
}
|
|
898
|
+
],
|
|
899
|
+
"transformers": [
|
|
900
|
+
"removeNulls"
|
|
901
|
+
]
|
|
902
|
+
},
|
|
858
903
|
{
|
|
859
904
|
"id": "crs-941-130",
|
|
860
905
|
"name": "XSS Filter - Category 3: Attribute Vector",
|
|
@@ -128,6 +128,12 @@ module Datadog
|
|
|
128
128
|
@options[:ruleset]
|
|
129
129
|
end
|
|
130
130
|
|
|
131
|
+
# EXPERIMENTAL: This configurable is not meant to be publicly used, but
|
|
132
|
+
# is very useful for testing. It may change at any point in time.
|
|
133
|
+
def ip_denylist
|
|
134
|
+
@options[:ip_denylist]
|
|
135
|
+
end
|
|
136
|
+
|
|
131
137
|
def waf_timeout
|
|
132
138
|
@options[:waf_timeout]
|
|
133
139
|
end
|
|
@@ -15,9 +15,7 @@ module Datadog
|
|
|
15
15
|
op.publish('request.headers', Rack::Request.headers(request))
|
|
16
16
|
op.publish('request.uri.raw', Rack::Request.url(request))
|
|
17
17
|
op.publish('request.cookies', Rack::Request.cookies(request))
|
|
18
|
-
|
|
19
|
-
# TODO: op.publish('request.path_params', { k: v }) # route params only?
|
|
20
|
-
# TODO: op.publish('request.path', request.script_name + request.path) # unused for now
|
|
18
|
+
op.publish('request.client_ip', Rack::Request.client_ip(request))
|
|
21
19
|
|
|
22
20
|
nil
|
|
23
21
|
end
|
|
@@ -30,8 +28,7 @@ module Datadog
|
|
|
30
28
|
'request.uri.raw',
|
|
31
29
|
'request.query',
|
|
32
30
|
'request.cookies',
|
|
33
|
-
|
|
34
|
-
# TODO: 'request.path_params',
|
|
31
|
+
'request.client_ip',
|
|
35
32
|
]
|
|
36
33
|
|
|
37
34
|
op.subscribe(*addresses) do |*values|
|
|
@@ -41,16 +38,15 @@ module Datadog
|
|
|
41
38
|
uri_raw = values[1]
|
|
42
39
|
query = values[2]
|
|
43
40
|
cookies = values[3]
|
|
44
|
-
|
|
41
|
+
client_ip = values[4]
|
|
45
42
|
|
|
46
43
|
waf_args = {
|
|
47
44
|
'server.request.cookies' => cookies,
|
|
48
|
-
# 'server.request.body.raw' => body,
|
|
49
45
|
'server.request.query' => query,
|
|
50
46
|
'server.request.uri.raw' => uri_raw,
|
|
51
47
|
'server.request.headers' => headers,
|
|
52
48
|
'server.request.headers.no_cookies' => headers_no_cookies,
|
|
53
|
-
|
|
49
|
+
'http.client_ip' => client_ip,
|
|
54
50
|
}
|
|
55
51
|
|
|
56
52
|
waf_timeout = Datadog::AppSec.settings.waf_timeout
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# typed: true
|
|
2
2
|
|
|
3
|
+
require_relative '../../../tracing/client_ip'
|
|
4
|
+
require_relative '../../../tracing/contrib/rack/header_collection'
|
|
5
|
+
|
|
3
6
|
module Datadog
|
|
4
7
|
module AppSec
|
|
5
8
|
module Contrib
|
|
@@ -54,6 +57,20 @@ module Datadog
|
|
|
54
57
|
# Hash<String,String||Array||Hash> when e.g coming from JSON
|
|
55
58
|
request.env['rack.request.form_hash']
|
|
56
59
|
end
|
|
60
|
+
|
|
61
|
+
def self.client_ip(request)
|
|
62
|
+
remote_ip = request.env['REMOTE_ADDR']
|
|
63
|
+
headers = Datadog::Tracing::Contrib::Rack::Header::RequestHeaderCollection.new(request.env)
|
|
64
|
+
|
|
65
|
+
result = Datadog::Tracing::ClientIp.raw_ip_from_request(headers, remote_ip)
|
|
66
|
+
|
|
67
|
+
if result.raw_ip
|
|
68
|
+
ip = Datadog::Tracing::ClientIp.strip_decorations(result.raw_ip)
|
|
69
|
+
return unless Datadog::Tracing::ClientIp.valid_ip?(ip)
|
|
70
|
+
|
|
71
|
+
ip
|
|
72
|
+
end
|
|
73
|
+
end
|
|
57
74
|
end
|
|
58
75
|
end
|
|
59
76
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# typed: ignore
|
|
2
2
|
|
|
3
3
|
require_relative '../../instrumentation/gateway'
|
|
4
|
-
require_relative '../../
|
|
4
|
+
require_relative '../../response'
|
|
5
5
|
|
|
6
6
|
module Datadog
|
|
7
7
|
module AppSec
|
|
@@ -29,7 +29,7 @@ module Datadog
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
if request_response && request_response.any? { |action, _event| action == :block }
|
|
32
|
-
request_return =
|
|
32
|
+
request_return = AppSec::Response.negotiate(env).to_rack
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
request_return
|
|
@@ -4,7 +4,7 @@ require 'json'
|
|
|
4
4
|
|
|
5
5
|
require_relative '../../instrumentation/gateway'
|
|
6
6
|
require_relative '../../processor'
|
|
7
|
-
require_relative '../../
|
|
7
|
+
require_relative '../../response'
|
|
8
8
|
|
|
9
9
|
require_relative '../../../tracing/client_ip'
|
|
10
10
|
require_relative '../../../tracing/contrib/rack/header_collection'
|
|
@@ -40,7 +40,7 @@ module Datadog
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
if request_response && request_response.any? { |action, _event| action == :block }
|
|
43
|
-
request_return =
|
|
43
|
+
request_return = AppSec::Response.negotiate(env).to_rack
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
response = ::Rack::Response.new(request_return[2], request_return[0], request_return[1])
|
|
@@ -4,6 +4,7 @@ require_relative '../../../core/utils/only_once'
|
|
|
4
4
|
|
|
5
5
|
require_relative '../patcher'
|
|
6
6
|
require_relative 'framework'
|
|
7
|
+
require_relative '../../response'
|
|
7
8
|
require_relative '../rack/request_middleware'
|
|
8
9
|
require_relative '../rack/request_body_middleware'
|
|
9
10
|
require_relative 'gateway/watcher'
|
|
@@ -83,11 +84,7 @@ module Datadog
|
|
|
83
84
|
end
|
|
84
85
|
|
|
85
86
|
if request_response && request_response.any? { |action, _event| action == :block }
|
|
86
|
-
@_response = ::
|
|
87
|
-
403,
|
|
88
|
-
{ 'Content-Type' => 'text/html' },
|
|
89
|
-
[Datadog::AppSec::Assets.blocked]
|
|
90
|
-
)
|
|
87
|
+
@_response = AppSec::Response.negotiate(env).to_action_dispatch_response
|
|
91
88
|
request_return = @_response.body
|
|
92
89
|
end
|
|
93
90
|
|
|
@@ -96,7 +93,7 @@ module Datadog
|
|
|
96
93
|
end
|
|
97
94
|
|
|
98
95
|
def patch_process_action
|
|
99
|
-
ActionController::
|
|
96
|
+
::ActionController::Metal.prepend(ProcessActionPatch)
|
|
100
97
|
end
|
|
101
98
|
|
|
102
99
|
def include_middleware?(middleware, app)
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require_relative '../../../tracing/contrib/rack/middlewares'
|
|
4
4
|
|
|
5
5
|
require_relative '../patcher'
|
|
6
|
+
require_relative '../../response'
|
|
6
7
|
require_relative '../rack/request_middleware'
|
|
7
8
|
require_relative 'framework'
|
|
8
9
|
require_relative 'gateway/watcher'
|
|
@@ -57,15 +58,12 @@ module Datadog
|
|
|
57
58
|
# TODO: handle exceptions, except for super
|
|
58
59
|
|
|
59
60
|
request_return, request_response = Instrumentation.gateway.push('sinatra.request.dispatch', request) do
|
|
60
|
-
|
|
61
|
+
# handle process_route interruption
|
|
62
|
+
catch(Ext::ROUTE_INTERRUPT) { super }
|
|
61
63
|
end
|
|
62
64
|
|
|
63
65
|
if request_response && request_response.any? { |action, _event| action == :block }
|
|
64
|
-
self.response = ::
|
|
65
|
-
[Datadog::AppSec::Assets.blocked],
|
|
66
|
-
403,
|
|
67
|
-
{ 'Content-Type' => 'text/html' }
|
|
68
|
-
)
|
|
66
|
+
self.response = AppSec::Response.negotiate(env).to_sinatra_response
|
|
69
67
|
request_return = nil
|
|
70
68
|
end
|
|
71
69
|
|
|
@@ -94,9 +92,14 @@ module Datadog
|
|
|
94
92
|
# At this point params has both route params and normal params.
|
|
95
93
|
route_params = params.each.with_object({}) { |(k, v), h| h[k] = v unless base_params.key?(k) }
|
|
96
94
|
|
|
97
|
-
Instrumentation.gateway.push('sinatra.request.routed', [request, route_params])
|
|
95
|
+
_, request_response = Instrumentation.gateway.push('sinatra.request.routed', [request, route_params])
|
|
98
96
|
|
|
99
|
-
|
|
97
|
+
if request_response && request_response.any? { |action, _event| action == :block }
|
|
98
|
+
self.response = AppSec::Response.negotiate(env).to_sinatra_response
|
|
99
|
+
|
|
100
|
+
# interrupt request and return response to dispatch! for consistency
|
|
101
|
+
throw(Ext::ROUTE_INTERRUPT, response)
|
|
102
|
+
end
|
|
100
103
|
|
|
101
104
|
yield(*args)
|
|
102
105
|
end
|
|
@@ -53,6 +53,12 @@ module Datadog
|
|
|
53
53
|
@settings.merge(dsl)
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
+
def ip_denylist=(arg)
|
|
57
|
+
dsl = AppSec::Configuration::DSL.new
|
|
58
|
+
dsl.ip_denylist = arg
|
|
59
|
+
@settings.merge(dsl)
|
|
60
|
+
end
|
|
61
|
+
|
|
56
62
|
def instrument(*args)
|
|
57
63
|
dsl = AppSec::Configuration::DSL.new
|
|
58
64
|
dsl.instrument(*args)
|
|
@@ -86,6 +92,10 @@ module Datadog
|
|
|
86
92
|
@settings.ruleset
|
|
87
93
|
end
|
|
88
94
|
|
|
95
|
+
def ruledata
|
|
96
|
+
@settings.ruledata
|
|
97
|
+
end
|
|
98
|
+
|
|
89
99
|
def waf_timeout
|
|
90
100
|
@settings.waf_timeout
|
|
91
101
|
end
|
|
@@ -57,7 +57,11 @@ module Datadog
|
|
|
57
57
|
|
|
58
58
|
unless load_libddwaf && load_ruleset && create_waf_handle
|
|
59
59
|
Datadog.logger.warn { 'AppSec is disabled, see logged errors above' }
|
|
60
|
+
|
|
61
|
+
return
|
|
60
62
|
end
|
|
63
|
+
|
|
64
|
+
update_ip_denylist
|
|
61
65
|
end
|
|
62
66
|
|
|
63
67
|
def ready?
|
|
@@ -76,6 +80,20 @@ module Datadog
|
|
|
76
80
|
@handle.toggle_rules(map)
|
|
77
81
|
end
|
|
78
82
|
|
|
83
|
+
def update_ip_denylist(denylist = Datadog::AppSec.settings.ip_denylist, id: 'blocked_ips')
|
|
84
|
+
denylist ||= []
|
|
85
|
+
|
|
86
|
+
ruledata_setting = [
|
|
87
|
+
{
|
|
88
|
+
'id' => id,
|
|
89
|
+
'type' => 'data_with_expiration',
|
|
90
|
+
'data' => denylist.map { |ip| { 'value' => ip.to_s, 'expiration' => 2**63 } }
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
|
|
94
|
+
update_rule_data(ruledata_setting)
|
|
95
|
+
end
|
|
96
|
+
|
|
79
97
|
def finalize
|
|
80
98
|
@handle.finalize
|
|
81
99
|
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# typed: false
|
|
2
|
+
|
|
3
|
+
require_relative 'assets'
|
|
4
|
+
|
|
5
|
+
module Datadog
|
|
6
|
+
module AppSec
|
|
7
|
+
# AppSec response
|
|
8
|
+
class Response
|
|
9
|
+
attr_reader :status, :headers, :body
|
|
10
|
+
|
|
11
|
+
def initialize(status:, headers: {}, body: [])
|
|
12
|
+
@status = status
|
|
13
|
+
@headers = headers
|
|
14
|
+
@body = body
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_rack
|
|
18
|
+
[status, headers, body]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def to_sinatra_response
|
|
22
|
+
::Sinatra::Response.new(body, status, headers)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def to_action_dispatch_response
|
|
26
|
+
::ActionDispatch::Response.new(status, headers, body)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class << self
|
|
30
|
+
def negotiate(env)
|
|
31
|
+
Response.new(
|
|
32
|
+
status: 403,
|
|
33
|
+
headers: { 'Content-Type' => 'text/html' },
|
|
34
|
+
body: [Datadog::AppSec::Assets.blocked(format: format(env))]
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def format(env)
|
|
41
|
+
format = env['HTTP_ACCEPT'] && env['HTTP_ACCEPT'].split(',').any? do |accept|
|
|
42
|
+
if accept.start_with?('text/html')
|
|
43
|
+
break :html
|
|
44
|
+
elsif accept.start_with?('application/json')
|
|
45
|
+
break :json
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
format || :text
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
# typed: true
|
|
2
2
|
|
|
3
3
|
require_relative '../tracing/span'
|
|
4
|
-
require_relative '../tracing/distributed/
|
|
4
|
+
require_relative '../tracing/distributed/datadog'
|
|
5
5
|
|
|
6
6
|
module Datadog
|
|
7
7
|
module OpenTracer
|
|
8
8
|
# DistributedHeaders provides easy access and validation to headers
|
|
9
9
|
# @public_api
|
|
10
10
|
class DistributedHeaders
|
|
11
|
-
include Tracing::Distributed::Headers::Ext
|
|
12
|
-
|
|
13
11
|
def initialize(carrier)
|
|
14
12
|
@carrier = carrier
|
|
15
13
|
end
|
|
@@ -20,15 +18,15 @@ module Datadog
|
|
|
20
18
|
end
|
|
21
19
|
|
|
22
20
|
def trace_id
|
|
23
|
-
id
|
|
21
|
+
id Tracing::Distributed::Datadog::TRACE_ID_KEY
|
|
24
22
|
end
|
|
25
23
|
|
|
26
24
|
def parent_id
|
|
27
|
-
id
|
|
25
|
+
id Tracing::Distributed::Datadog::PARENT_ID_KEY
|
|
28
26
|
end
|
|
29
27
|
|
|
30
28
|
def sampling_priority
|
|
31
|
-
hdr = @carrier[
|
|
29
|
+
hdr = @carrier[Tracing::Distributed::Datadog::SAMPLING_PRIORITY_KEY]
|
|
32
30
|
# It's important to make a difference between no header,
|
|
33
31
|
# and a header defined to zero.
|
|
34
32
|
return unless hdr
|
|
@@ -40,7 +38,7 @@ module Datadog
|
|
|
40
38
|
end
|
|
41
39
|
|
|
42
40
|
def origin
|
|
43
|
-
hdr = @carrier[
|
|
41
|
+
hdr = @carrier[Tracing::Distributed::Datadog::ORIGIN_KEY]
|
|
44
42
|
# Only return the value if it is not an empty string
|
|
45
43
|
hdr if hdr != ''
|
|
46
44
|
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# typed: true
|
|
2
2
|
|
|
3
3
|
require_relative '../tracing/context'
|
|
4
|
-
require_relative '../tracing/distributed/headers/ext'
|
|
5
4
|
require_relative '../tracing/propagation/http'
|
|
6
5
|
require_relative '../tracing/trace_operation'
|
|
7
6
|
require_relative 'propagator'
|
|
@@ -11,8 +10,6 @@ module Datadog
|
|
|
11
10
|
# OpenTracing propagator for Datadog::OpenTracer::Tracer
|
|
12
11
|
module RackPropagator
|
|
13
12
|
extend Propagator
|
|
14
|
-
extend Tracing::Distributed::Headers::Ext
|
|
15
|
-
include Tracing::Distributed::Headers::Ext
|
|
16
13
|
|
|
17
14
|
BAGGAGE_PREFIX = 'ot-baggage-'.freeze
|
|
18
15
|
BAGGAGE_PREFIX_FORMATTED = 'HTTP_OT_BAGGAGE_'.freeze
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# typed: true
|
|
2
2
|
|
|
3
3
|
require_relative '../tracing/context'
|
|
4
|
-
require_relative '../tracing/distributed/
|
|
4
|
+
require_relative '../tracing/distributed/datadog'
|
|
5
5
|
require_relative '../tracing/trace_operation'
|
|
6
6
|
require_relative 'propagator'
|
|
7
7
|
|
|
@@ -10,8 +10,6 @@ module Datadog
|
|
|
10
10
|
# OpenTracing propagator for Datadog::OpenTracer::Tracer
|
|
11
11
|
module TextMapPropagator
|
|
12
12
|
extend Propagator
|
|
13
|
-
extend Tracing::Distributed::Headers::Ext
|
|
14
|
-
include Tracing::Distributed::Headers::Ext
|
|
15
13
|
|
|
16
14
|
BAGGAGE_PREFIX = 'ot-baggage-'.freeze
|
|
17
15
|
|
|
@@ -34,10 +32,10 @@ module Datadog
|
|
|
34
32
|
end
|
|
35
33
|
return unless digest
|
|
36
34
|
|
|
37
|
-
carrier[
|
|
38
|
-
carrier[
|
|
39
|
-
carrier[
|
|
40
|
-
carrier[
|
|
35
|
+
carrier[Tracing::Distributed::Datadog::ORIGIN_KEY] = digest.trace_origin
|
|
36
|
+
carrier[Tracing::Distributed::Datadog::PARENT_ID_KEY] = digest.span_id
|
|
37
|
+
carrier[Tracing::Distributed::Datadog::SAMPLING_PRIORITY_KEY] = digest.trace_sampling_priority
|
|
38
|
+
carrier[Tracing::Distributed::Datadog::TRACE_ID_KEY] = digest.trace_id
|
|
41
39
|
|
|
42
40
|
nil
|
|
43
41
|
end
|
|
@@ -23,13 +23,19 @@ module Datadog
|
|
|
23
23
|
result
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
def reset_after_fork
|
|
27
|
+
self.class._native_reset_after_fork(self)
|
|
28
|
+
end
|
|
29
|
+
|
|
26
30
|
private
|
|
27
31
|
|
|
28
32
|
def safely_extract_context_key_from(tracer)
|
|
29
|
-
tracer &&
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
provider = tracer && tracer.respond_to?(:provider) && tracer.provider
|
|
34
|
+
|
|
35
|
+
return unless provider
|
|
36
|
+
|
|
37
|
+
context = provider.instance_variable_get(:@context)
|
|
38
|
+
context && context.instance_variable_get(:@key)
|
|
33
39
|
end
|
|
34
40
|
end
|
|
35
41
|
end
|