ddtrace 1.6.1 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +89 -2
- data/README.md +2 -2
- data/ext/ddtrace_profiling_loader/extconf.rb +5 -2
- data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +1 -1
- data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +3 -2
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +81 -47
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.h +1 -1
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +332 -125
- data/ext/ddtrace_profiling_native_extension/collectors_dynamic_sampling_rate.c +142 -0
- data/ext/ddtrace_profiling_native_extension/collectors_dynamic_sampling_rate.h +14 -0
- data/ext/ddtrace_profiling_native_extension/collectors_idle_sampling_helper.c +241 -0
- data/ext/ddtrace_profiling_native_extension/collectors_idle_sampling_helper.h +3 -0
- data/ext/ddtrace_profiling_native_extension/collectors_stack.c +11 -13
- data/ext/ddtrace_profiling_native_extension/extconf.rb +22 -8
- data/ext/ddtrace_profiling_native_extension/helpers.h +5 -0
- data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +8 -0
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +111 -26
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +9 -0
- data/ext/ddtrace_profiling_native_extension/profiling.c +205 -0
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.c +86 -0
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.h +28 -6
- data/ext/ddtrace_profiling_native_extension/setup_signal_handler.c +115 -0
- data/ext/ddtrace_profiling_native_extension/setup_signal_handler.h +11 -0
- data/ext/ddtrace_profiling_native_extension/stack_recorder.c +84 -35
- data/ext/ddtrace_profiling_native_extension/stack_recorder.h +1 -0
- data/ext/ddtrace_profiling_native_extension/time_helpers.c +17 -0
- data/ext/ddtrace_profiling_native_extension/time_helpers.h +10 -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/configuration/components.rb +27 -6
- data/lib/datadog/core/configuration/ext.rb +18 -0
- data/lib/datadog/core/configuration/settings.rb +14 -341
- data/lib/datadog/core/diagnostics/health.rb +4 -22
- data/lib/datadog/core/environment/variable_helpers.rb +58 -10
- data/lib/datadog/core/runtime/ext.rb +1 -1
- data/lib/datadog/core/utils.rb +0 -21
- data/lib/datadog/core.rb +21 -1
- data/lib/datadog/opentracer/distributed_headers.rb +7 -9
- 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 +20 -5
- data/lib/datadog/profiling/collectors/dynamic_sampling_rate.rb +14 -0
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +68 -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 +36 -0
- data/lib/datadog/profiling/tasks/setup.rb +0 -7
- data/lib/datadog/profiling.rb +2 -0
- data/lib/datadog/tracing/configuration/ext.rb +33 -3
- data/lib/datadog/tracing/configuration/settings.rb +433 -0
- data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/aws/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/dalli/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/delayed_job/plugin.rb +4 -0
- data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/ethon/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/excon/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/faraday/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +6 -1
- 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 +43 -0
- data/lib/datadog/tracing/contrib/grpc/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/grpc/patcher.rb +0 -2
- data/lib/datadog/tracing/contrib/http/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +32 -0
- data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +38 -0
- data/lib/datadog/tracing/contrib/http/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/httpclient/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/httprb/ext.rb +1 -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/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +2 -0
- data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/patcher.rb +3 -2
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/pg/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +12 -2
- data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/presto/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +10 -12
- 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/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/redis/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/redis/instrumentation.rb +30 -21
- data/lib/datadog/tracing/contrib/redis/integration.rb +34 -2
- data/lib/datadog/tracing/contrib/redis/patcher.rb +18 -14
- data/lib/datadog/tracing/contrib/redis/quantize.rb +12 -9
- data/lib/datadog/tracing/contrib/redis/tags.rb +4 -6
- data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +72 -0
- data/lib/datadog/tracing/contrib/resque/resque_job.rb +2 -0
- data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/rest_client/ext.rb +1 -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/{core → tracing}/diagnostics/ext.rb +1 -6
- data/lib/datadog/tracing/diagnostics/health.rb +40 -0
- data/lib/datadog/tracing/distributed/b3_multi.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 +9 -7
- data/lib/datadog/tracing/distributed/none.rb +19 -0
- data/lib/datadog/tracing/distributed/propagation.rb +127 -0
- data/lib/datadog/tracing/distributed/trace_context.rb +369 -0
- data/lib/datadog/tracing/metadata/ext.rb +1 -1
- data/lib/datadog/tracing/propagation/http.rb +3 -106
- data/lib/datadog/tracing/sampling/priority_sampler.rb +11 -0
- data/lib/datadog/tracing/sampling/rate_sampler.rb +3 -3
- data/lib/datadog/tracing/span.rb +3 -19
- data/lib/datadog/tracing/span_operation.rb +5 -4
- data/lib/datadog/tracing/trace_digest.rb +75 -2
- data/lib/datadog/tracing/trace_operation.rb +5 -4
- data/lib/datadog/tracing/trace_segment.rb +1 -1
- data/lib/datadog/tracing/utils.rb +50 -0
- data/lib/ddtrace/transport/trace_formatter.rb +2 -5
- data/lib/ddtrace/version.rb +2 -2
- metadata +35 -15
- 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
|
@@ -248,6 +248,8 @@ module Datadog
|
|
248
248
|
# NOTE: Please update the Initialization section of ProfilingDevelopment.md with any changes to this method
|
249
249
|
|
250
250
|
if settings.profiling.advanced.force_enable_new_profiler
|
251
|
+
print_new_profiler_warnings
|
252
|
+
|
251
253
|
recorder = Datadog::Profiling::StackRecorder.new
|
252
254
|
collector = Datadog::Profiling::Collectors::CpuAndWallTimeWorker.new(
|
253
255
|
recorder: recorder,
|
@@ -331,20 +333,39 @@ module Datadog
|
|
331
333
|
end
|
332
334
|
|
333
335
|
def should_enable_gc_profiling?(settings)
|
334
|
-
return true if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3')
|
335
|
-
|
336
336
|
# See comments on the setting definition for more context on why it exists.
|
337
337
|
if settings.profiling.advanced.force_enable_gc_profiling
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
338
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3')
|
339
|
+
Datadog.logger.debug(
|
340
|
+
'Profiling time/resources spent in Garbage Collection force enabled. Do not use Ractors in combination ' \
|
341
|
+
'with this option as profiles will be incomplete.'
|
342
|
+
)
|
343
|
+
end
|
342
344
|
|
343
345
|
true
|
344
346
|
else
|
345
347
|
false
|
346
348
|
end
|
347
349
|
end
|
350
|
+
|
351
|
+
def print_new_profiler_warnings
|
352
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6')
|
353
|
+
Datadog.logger.warn(
|
354
|
+
'New Ruby profiler has been force-enabled. This feature is in beta state. We do not yet recommend ' \
|
355
|
+
'running it in production environments. Please report any issues ' \
|
356
|
+
'you run into to Datadog support or via <https://github.com/datadog/dd-trace-rb/issues/new>!'
|
357
|
+
)
|
358
|
+
else
|
359
|
+
# For more details on the issue, see the "BIG Issue" comment on `gvl_owner` function in
|
360
|
+
# `private_vm_api_access.c`.
|
361
|
+
Datadog.logger.warn(
|
362
|
+
'New Ruby profiler has been force-enabled on a legacy Ruby version (< 2.6). This is not recommended in ' \
|
363
|
+
'production environments, as due to limitations in Ruby APIs, we suspect it may lead to crashes in very ' \
|
364
|
+
'rare situations. Please report any issues you run into to Datadog support or ' \
|
365
|
+
'via <https://github.com/datadog/dd-trace-rb/issues/new>!'
|
366
|
+
)
|
367
|
+
end
|
368
|
+
end
|
348
369
|
end
|
349
370
|
|
350
371
|
attr_reader \
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# typed: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module Core
|
5
|
+
module Configuration
|
6
|
+
# Constants for configuration settings
|
7
|
+
# e.g. Env vars, default values, enums, etc...
|
8
|
+
module Ext
|
9
|
+
# @public_api
|
10
|
+
module Diagnostics
|
11
|
+
ENV_DEBUG_ENABLED = 'DD_TRACE_DEBUG'.freeze
|
12
|
+
ENV_HEALTH_METRICS_ENABLED = 'DD_HEALTH_METRICS_ENABLED'.freeze
|
13
|
+
ENV_STARTUP_LOGS_ENABLED = 'DD_TRACE_STARTUP_LOGS'.freeze
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|