datadog 2.10.0 → 2.11.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 +46 -1
- data/ext/datadog_profiling_native_extension/collectors_stack.c +3 -3
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +44 -1
- data/ext/datadog_profiling_native_extension/extconf.rb +4 -0
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +2 -0
- data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +0 -8
- data/ext/datadog_profiling_native_extension/heap_recorder.c +1 -1
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +56 -0
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +7 -0
- data/ext/datadog_profiling_native_extension/profiling.c +7 -0
- data/ext/libdatadog_api/crashtracker.c +4 -4
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/appsec/configuration/settings.rb +64 -11
- data/lib/datadog/appsec/contrib/active_record/patcher.rb +0 -3
- data/lib/datadog/appsec/contrib/devise/configuration.rb +76 -0
- data/lib/datadog/appsec/contrib/devise/event.rb +4 -7
- data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +16 -21
- data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +8 -15
- data/lib/datadog/appsec/contrib/devise/patcher/rememberable_patch.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/patcher.rb +0 -3
- data/lib/datadog/appsec/contrib/devise/tracking.rb +1 -1
- data/lib/datadog/appsec/contrib/excon/integration.rb +41 -0
- data/lib/datadog/appsec/contrib/excon/patcher.rb +28 -0
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +43 -0
- data/lib/datadog/appsec/contrib/faraday/connection_patch.rb +22 -0
- data/lib/datadog/appsec/contrib/faraday/integration.rb +42 -0
- data/lib/datadog/appsec/contrib/faraday/patcher.rb +53 -0
- data/lib/datadog/appsec/contrib/faraday/rack_builder_patch.rb +22 -0
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +42 -0
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +10 -12
- data/lib/datadog/appsec/contrib/graphql/patcher.rb +0 -3
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +65 -73
- data/lib/datadog/appsec/contrib/rack/patcher.rb +0 -3
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +20 -25
- data/lib/datadog/appsec/contrib/rails/patcher.rb +0 -3
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +38 -49
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +0 -3
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +19 -25
- data/lib/datadog/appsec/remote.rb +4 -0
- data/lib/datadog/appsec.rb +2 -0
- data/lib/datadog/core/configuration/components.rb +7 -1
- data/lib/datadog/core/configuration/ext.rb +1 -1
- data/lib/datadog/core/configuration/option_definition.rb +2 -0
- data/lib/datadog/core/configuration/settings.rb +22 -6
- data/lib/datadog/core/encoding.rb +16 -0
- data/lib/datadog/core/environment/agent_info.rb +77 -0
- data/lib/datadog/core/remote/transport/http/api.rb +13 -18
- data/lib/datadog/core/remote/transport/http/config.rb +0 -18
- data/lib/datadog/core/remote/transport/http/negotiation.rb +1 -18
- data/lib/datadog/core/remote/transport/http.rb +7 -12
- data/lib/datadog/core/remote/transport/negotiation.rb +13 -1
- data/lib/datadog/core/telemetry/event.rb +5 -0
- data/lib/datadog/core/transport/http/adapters/unix_socket.rb +1 -1
- data/lib/datadog/{tracing → core}/transport/http/api/instance.rb +1 -1
- data/lib/datadog/{tracing → core}/transport/http/api/spec.rb +1 -1
- data/lib/datadog/{tracing → core}/transport/http/builder.rb +37 -17
- data/lib/datadog/core/transport/response.rb +4 -0
- data/lib/datadog/di/code_tracker.rb +15 -8
- data/lib/datadog/di/component.rb +1 -0
- data/lib/datadog/di/configuration/settings.rb +14 -0
- data/lib/datadog/di/contrib.rb +2 -0
- data/lib/datadog/di/logger.rb +30 -0
- data/lib/datadog/di/probe.rb +3 -6
- data/lib/datadog/di/probe_manager.rb +5 -2
- data/lib/datadog/di/probe_notifier_worker.rb +15 -4
- data/lib/datadog/di/remote.rb +3 -3
- data/lib/datadog/di/utils.rb +91 -0
- data/lib/datadog/di.rb +3 -0
- data/lib/datadog/profiling/component.rb +2 -8
- data/lib/datadog/profiling/load_native_extension.rb +1 -33
- data/lib/datadog/tracing/configuration/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/extensions.rb +14 -0
- data/lib/datadog/tracing/contrib/graphql/configuration/error_extension_env_parser.rb +21 -0
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +11 -0
- data/lib/datadog/tracing/contrib/graphql/ext.rb +5 -0
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +102 -11
- data/lib/datadog/tracing/contrib/rack/header_collection.rb +11 -1
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +1 -1
- data/lib/datadog/tracing/contrib/span_attribute_schema.rb +6 -1
- data/lib/datadog/tracing/transport/http/api.rb +11 -2
- data/lib/datadog/tracing/transport/http/traces.rb +0 -3
- data/lib/datadog/tracing/transport/http.rb +12 -7
- data/lib/datadog/tracing/transport/serializable_trace.rb +8 -4
- data/lib/datadog/tracing/transport/traces.rb +25 -8
- data/lib/datadog/version.rb +1 -1
- metadata +23 -28
- data/ext/datadog_profiling_loader/datadog_profiling_loader.c +0 -142
- data/ext/datadog_profiling_loader/extconf.rb +0 -60
- data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +0 -46
- data/lib/datadog/appsec/contrib/patcher.rb +0 -12
- data/lib/datadog/appsec/contrib/rack/reactive/request.rb +0 -69
- data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +0 -47
- data/lib/datadog/appsec/contrib/rack/reactive/response.rb +0 -53
- data/lib/datadog/appsec/contrib/rails/reactive/action.rb +0 -53
- data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +0 -48
- data/lib/datadog/appsec/monitor/reactive/set_user.rb +0 -45
- data/lib/datadog/appsec/reactive/address_hash.rb +0 -22
- data/lib/datadog/appsec/reactive/engine.rb +0 -47
- data/lib/datadog/appsec/reactive/subscriber.rb +0 -19
- data/lib/datadog/core/remote/transport/http/api/instance.rb +0 -39
- data/lib/datadog/core/remote/transport/http/api/spec.rb +0 -21
- data/lib/datadog/core/remote/transport/http/builder.rb +0 -219
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../configuration'
|
3
4
|
require_relative '../tracking'
|
4
5
|
require_relative '../resource'
|
5
6
|
require_relative '../event'
|
@@ -14,33 +15,27 @@ module Datadog
|
|
14
15
|
# rubocop:disable Metrics/MethodLength
|
15
16
|
def validate(resource, &block)
|
16
17
|
result = super
|
17
|
-
return result unless AppSec.enabled?
|
18
|
-
return result if @_datadog_skip_track_login_event
|
19
|
-
|
20
|
-
track_user_events_configuration = Datadog.configuration.appsec.track_user_events
|
21
|
-
|
22
|
-
return result unless track_user_events_configuration.enabled
|
23
|
-
|
24
|
-
automated_track_user_events_mode = track_user_events_configuration.mode
|
25
18
|
|
26
|
-
|
27
|
-
|
28
|
-
return result unless
|
19
|
+
return result unless AppSec.enabled?
|
20
|
+
return result if @_datadog_appsec_skip_track_login_event
|
21
|
+
return result unless Configuration.auto_user_instrumentation_enabled?
|
22
|
+
return result unless AppSec.active_context
|
29
23
|
|
30
24
|
devise_resource = resource ? Resource.new(resource) : nil
|
31
|
-
|
32
|
-
event_information = Event.new(devise_resource, automated_track_user_events_mode)
|
25
|
+
event_information = Event.new(devise_resource, Configuration.auto_user_instrumentation_mode)
|
33
26
|
|
34
27
|
if result
|
35
28
|
if event_information.user_id
|
36
|
-
Datadog.logger.debug { 'User
|
29
|
+
Datadog.logger.debug { 'AppSec: User successful login event' }
|
37
30
|
else
|
38
|
-
Datadog.logger.debug
|
31
|
+
Datadog.logger.debug do
|
32
|
+
"AppSec: User successful login event, but can't extract user ID. Tracking empty event"
|
33
|
+
end
|
39
34
|
end
|
40
35
|
|
41
36
|
Tracking.track_login_success(
|
42
|
-
|
43
|
-
|
37
|
+
AppSec.active_context.trace,
|
38
|
+
AppSec.active_context.span,
|
44
39
|
user_id: event_information.user_id,
|
45
40
|
**event_information.to_h
|
46
41
|
)
|
@@ -52,15 +47,15 @@ module Datadog
|
|
52
47
|
|
53
48
|
if resource
|
54
49
|
user_exists = true
|
55
|
-
Datadog.logger.debug { 'User
|
50
|
+
Datadog.logger.debug { 'AppSec: User failed login event, but user exists' }
|
56
51
|
else
|
57
52
|
user_exists = false
|
58
|
-
Datadog.logger.debug { 'User
|
53
|
+
Datadog.logger.debug { 'AppSec: User failed login event and user does not exist' }
|
59
54
|
end
|
60
55
|
|
61
56
|
Tracking.track_login_failure(
|
62
|
-
|
63
|
-
|
57
|
+
AppSec.active_context.trace,
|
58
|
+
AppSec.active_context.span,
|
64
59
|
user_id: event_information.user_id,
|
65
60
|
user_exists: user_exists,
|
66
61
|
**event_information.to_h
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../configuration'
|
3
4
|
require_relative '../tracking'
|
4
5
|
require_relative '../resource'
|
5
6
|
require_relative '../event'
|
@@ -13,31 +14,23 @@ module Datadog
|
|
13
14
|
module RegistrationControllerPatch
|
14
15
|
def create
|
15
16
|
return super unless AppSec.enabled?
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
return super unless track_user_events_configuration.enabled
|
20
|
-
|
21
|
-
automated_track_user_events_mode = track_user_events_configuration.mode
|
22
|
-
|
23
|
-
appsec_context = Datadog::AppSec.active_context
|
24
|
-
return super unless appsec_context
|
17
|
+
return super unless Configuration.auto_user_instrumentation_enabled?
|
18
|
+
return super unless AppSec.active_context
|
25
19
|
|
26
20
|
super do |resource|
|
27
21
|
if resource.persisted?
|
28
22
|
devise_resource = Resource.new(resource)
|
29
|
-
|
30
|
-
event_information = Event.new(devise_resource, automated_track_user_events_mode)
|
23
|
+
event_information = Event.new(devise_resource, Configuration.auto_user_instrumentation_mode)
|
31
24
|
|
32
25
|
if event_information.user_id
|
33
|
-
Datadog.logger.debug { 'User
|
26
|
+
Datadog.logger.debug { 'AppSec: User signup event' }
|
34
27
|
else
|
35
|
-
Datadog.logger.warn {
|
28
|
+
Datadog.logger.warn { "AppSec: User signup event, but can't extract user ID. Tracking empty event" }
|
36
29
|
end
|
37
30
|
|
38
31
|
Tracking.track_signup(
|
39
|
-
|
40
|
-
|
32
|
+
AppSec.active_context.trace,
|
33
|
+
AppSec.active_context.span,
|
41
34
|
user_id: event_information.user_id,
|
42
35
|
**event_information.to_h
|
43
36
|
)
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../patcher'
|
4
3
|
require_relative 'patcher/authenticatable_patch'
|
5
4
|
require_relative 'patcher/rememberable_patch'
|
6
5
|
require_relative 'patcher/registration_controller_patch'
|
@@ -11,8 +10,6 @@ module Datadog
|
|
11
10
|
module Devise
|
12
11
|
# Patcher for AppSec on Devise
|
13
12
|
module Patcher
|
14
|
-
include Datadog::AppSec::Contrib::Patcher
|
15
|
-
|
16
13
|
module_function
|
17
14
|
|
18
15
|
def patched?
|
@@ -40,7 +40,7 @@ module Datadog
|
|
40
40
|
return if trace.nil? || span.nil?
|
41
41
|
|
42
42
|
span.set_tag("appsec.events.#{event}.track", 'true')
|
43
|
-
span.set_tag("_dd.appsec.events.#{event}.auto.mode",
|
43
|
+
span.set_tag("_dd.appsec.events.#{event}.auto.mode", Configuration.track_user_events_mode)
|
44
44
|
|
45
45
|
others.each do |k, v|
|
46
46
|
raise ArgumentError, 'key cannot be :track' if k.to_sym == :track
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../integration'
|
4
|
+
require_relative 'patcher'
|
5
|
+
|
6
|
+
module Datadog
|
7
|
+
module AppSec
|
8
|
+
module Contrib
|
9
|
+
module Excon
|
10
|
+
# This class provides helper methods that are used when patching Excon
|
11
|
+
class Integration
|
12
|
+
include Datadog::AppSec::Contrib::Integration
|
13
|
+
|
14
|
+
MINIMUM_VERSION = Gem::Version.new('0.50.0')
|
15
|
+
|
16
|
+
register_as :excon
|
17
|
+
|
18
|
+
def self.version
|
19
|
+
Gem.loaded_specs['excon'] && Gem.loaded_specs['excon'].version
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.loaded?
|
23
|
+
!defined?(::Excon).nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.compatible?
|
27
|
+
super && version >= MINIMUM_VERSION
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.auto_instrument?
|
31
|
+
false
|
32
|
+
end
|
33
|
+
|
34
|
+
def patcher
|
35
|
+
Patcher
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module AppSec
|
5
|
+
module Contrib
|
6
|
+
module Excon
|
7
|
+
# AppSec patcher module for Excon
|
8
|
+
module Patcher
|
9
|
+
module_function
|
10
|
+
|
11
|
+
def patched?
|
12
|
+
Patcher.instance_variable_get(:@patched)
|
13
|
+
end
|
14
|
+
|
15
|
+
def target_version
|
16
|
+
Integration.version
|
17
|
+
end
|
18
|
+
|
19
|
+
def patch
|
20
|
+
require_relative 'ssrf_detection_middleware'
|
21
|
+
|
22
|
+
::Excon.defaults[:middlewares].insert(0, SSRFDetectionMiddleware)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# rubocop:disable Naming/FileName
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'excon'
|
5
|
+
|
6
|
+
module Datadog
|
7
|
+
module AppSec
|
8
|
+
module Contrib
|
9
|
+
module Excon
|
10
|
+
# AppSec Middleware for Excon
|
11
|
+
class SSRFDetectionMiddleware < ::Excon::Middleware::Base
|
12
|
+
def request_call(data)
|
13
|
+
return super unless AppSec.rasp_enabled? && AppSec.active_context
|
14
|
+
|
15
|
+
context = AppSec.active_context
|
16
|
+
|
17
|
+
request_url = URI.join("#{data[:scheme]}://#{data[:host]}", data[:path]).to_s
|
18
|
+
ephemeral_data = { 'server.io.net.url' => request_url }
|
19
|
+
|
20
|
+
result = context.run_rasp(Ext::RASP_SSRF, {}, ephemeral_data, Datadog.configuration.appsec.waf_timeout)
|
21
|
+
|
22
|
+
if result.match?
|
23
|
+
Datadog::AppSec::Event.tag_and_keep!(context, result)
|
24
|
+
|
25
|
+
context.events << {
|
26
|
+
waf_result: result,
|
27
|
+
trace: context.trace,
|
28
|
+
span: context.span,
|
29
|
+
request_url: request_url,
|
30
|
+
actions: result.actions
|
31
|
+
}
|
32
|
+
|
33
|
+
ActionsHandler.handle(result.actions)
|
34
|
+
end
|
35
|
+
|
36
|
+
super
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
# rubocop:enable Naming/FileName
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module AppSec
|
5
|
+
module Contrib
|
6
|
+
module Faraday
|
7
|
+
# Handles installation of our middleware if the user has *not*
|
8
|
+
# already explicitly configured our middleware for this correction.
|
9
|
+
#
|
10
|
+
# Wraps Faraday::Connection#initialize:
|
11
|
+
# https://github.com/lostisland/faraday/blob/ff9dc1d1219a1bbdba95a9a4cf5d135b97247ee2/lib/faraday/connection.rb#L62-L92
|
12
|
+
module ConnectionPatch
|
13
|
+
def initialize(*args, &block)
|
14
|
+
super.tap do
|
15
|
+
use(:datadog_appsec) unless builder.handlers.any? { |h| h.klass == SSRFDetectionMiddleware }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../integration'
|
4
|
+
|
5
|
+
require_relative 'patcher'
|
6
|
+
|
7
|
+
module Datadog
|
8
|
+
module AppSec
|
9
|
+
module Contrib
|
10
|
+
module Faraday
|
11
|
+
# This class provides helper methods that are used when patching Faraday
|
12
|
+
class Integration
|
13
|
+
include Datadog::AppSec::Contrib::Integration
|
14
|
+
|
15
|
+
MINIMUM_VERSION = Gem::Version.new('0.14.0')
|
16
|
+
|
17
|
+
register_as :faraday, auto_patch: true
|
18
|
+
|
19
|
+
def self.version
|
20
|
+
Gem.loaded_specs['faraday'] && Gem.loaded_specs['faraday'].version
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.loaded?
|
24
|
+
!defined?(::Faraday).nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.compatible?
|
28
|
+
super && version >= MINIMUM_VERSION
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.auto_instrument?
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
def patcher
|
36
|
+
Patcher
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module AppSec
|
5
|
+
module Contrib
|
6
|
+
module Faraday
|
7
|
+
# Patcher for Faraday
|
8
|
+
module Patcher
|
9
|
+
module_function
|
10
|
+
|
11
|
+
def patched?
|
12
|
+
Patcher.instance_variable_get(:@patched)
|
13
|
+
end
|
14
|
+
|
15
|
+
def target_version
|
16
|
+
Integration.version
|
17
|
+
end
|
18
|
+
|
19
|
+
def patch
|
20
|
+
require_relative 'ssrf_detection_middleware'
|
21
|
+
require_relative 'connection_patch'
|
22
|
+
require_relative 'rack_builder_patch'
|
23
|
+
|
24
|
+
::Faraday::Middleware.register_middleware(datadog_appsec: SSRFDetectionMiddleware)
|
25
|
+
configure_default_faraday_connection
|
26
|
+
|
27
|
+
Patcher.instance_variable_set(:@patched, true)
|
28
|
+
end
|
29
|
+
|
30
|
+
def configure_default_faraday_connection
|
31
|
+
if target_version >= Gem::Version.new('1.0.0')
|
32
|
+
# Patch the default connection (e.g. +Faraday.get+)
|
33
|
+
::Faraday.default_connection.use(:datadog_appsec)
|
34
|
+
|
35
|
+
# Patch new connection instances (e.g. +Faraday.new+)
|
36
|
+
::Faraday::Connection.prepend(ConnectionPatch)
|
37
|
+
else
|
38
|
+
# Patch the default connection (e.g. +Faraday.get+)
|
39
|
+
#
|
40
|
+
# We insert our middleware before the 'adapter', which is
|
41
|
+
# always the last handler.
|
42
|
+
idx = ::Faraday.default_connection.builder.handlers.size - 1
|
43
|
+
::Faraday.default_connection.builder.insert(idx, SSRFDetectionMiddleware)
|
44
|
+
|
45
|
+
# Patch new connection instances (e.g. +Faraday.new+)
|
46
|
+
::Faraday::RackBuilder.prepend(RackBuilderPatch)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module AppSec
|
5
|
+
module Contrib
|
6
|
+
module Faraday
|
7
|
+
# Handles installation of our middleware if the user has *not*
|
8
|
+
# already explicitly configured it for this correction.
|
9
|
+
#
|
10
|
+
# RackBuilder class was introduced in faraday 0.9.0:
|
11
|
+
# https://github.com/lostisland/faraday/commit/77d7546d6d626b91086f427c56bc2cdd951353b3
|
12
|
+
module RackBuilderPatch
|
13
|
+
def adapter(*args)
|
14
|
+
use(:datadog_appsec) unless @handlers.any? { |h| h.klass == SSRFDetectionMiddleware }
|
15
|
+
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# rubocop:disable Naming/FileName
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Datadog
|
5
|
+
module AppSec
|
6
|
+
module Contrib
|
7
|
+
module Faraday
|
8
|
+
# AppSec SSRF detection Middleware for Faraday
|
9
|
+
class SSRFDetectionMiddleware < ::Faraday::Middleware
|
10
|
+
def call(request_env)
|
11
|
+
context = AppSec.active_context
|
12
|
+
|
13
|
+
return @app.call(request_env) unless context && AppSec.rasp_enabled?
|
14
|
+
|
15
|
+
ephemeral_data = {
|
16
|
+
'server.io.net.url' => request_env.url.to_s
|
17
|
+
}
|
18
|
+
|
19
|
+
result = context.run_rasp(Ext::RASP_SSRF, {}, ephemeral_data, Datadog.configuration.appsec.waf_timeout)
|
20
|
+
|
21
|
+
if result.match?
|
22
|
+
Datadog::AppSec::Event.tag_and_keep!(context, result)
|
23
|
+
|
24
|
+
context.events << {
|
25
|
+
waf_result: result,
|
26
|
+
trace: context.trace,
|
27
|
+
span: context.span,
|
28
|
+
request_url: request_env.url,
|
29
|
+
actions: result.actions
|
30
|
+
}
|
31
|
+
|
32
|
+
ActionsHandler.handle(result.actions)
|
33
|
+
end
|
34
|
+
|
35
|
+
@app.call(request_env)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
# rubocop:enable Naming/FileName
|
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
require 'json'
|
4
4
|
require_relative '../../../instrumentation/gateway'
|
5
|
-
require_relative '../../../reactive/engine'
|
6
|
-
require_relative '../reactive/multiplex'
|
7
5
|
|
8
6
|
module Datadog
|
9
7
|
module AppSec
|
@@ -19,16 +17,21 @@ module Datadog
|
|
19
17
|
watch_multiplex(gateway)
|
20
18
|
end
|
21
19
|
|
22
|
-
# This time we don't throw but use next
|
23
20
|
def watch_multiplex(gateway = Instrumentation.gateway)
|
24
21
|
gateway.watch('graphql.multiplex', :appsec) do |stack, gateway_multiplex|
|
25
|
-
event = nil
|
26
22
|
context = AppSec::Context.active
|
27
|
-
engine = AppSec::Reactive::Engine.new
|
28
23
|
|
29
24
|
if context
|
30
|
-
|
31
|
-
|
25
|
+
persistent_data = {
|
26
|
+
'graphql.server.all_resolvers' => gateway_multiplex.arguments
|
27
|
+
}
|
28
|
+
|
29
|
+
result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
|
30
|
+
|
31
|
+
if result.match?
|
32
|
+
Datadog::AppSec::Event.tag_and_keep!(context, result)
|
33
|
+
|
34
|
+
context.events << {
|
32
35
|
waf_result: result,
|
33
36
|
trace: context.trace,
|
34
37
|
span: context.span,
|
@@ -36,13 +39,8 @@ module Datadog
|
|
36
39
|
actions: result.actions
|
37
40
|
}
|
38
41
|
|
39
|
-
Datadog::AppSec::Event.tag_and_keep!(context, result)
|
40
|
-
context.events << event
|
41
|
-
|
42
42
|
Datadog::AppSec::ActionsHandler.handle(result.actions)
|
43
43
|
end
|
44
|
-
|
45
|
-
GraphQL::Reactive::Multiplex.publish(engine, gateway_multiplex)
|
46
44
|
end
|
47
45
|
|
48
46
|
stack.call(gateway_multiplex.arguments)
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../patcher'
|
4
3
|
require_relative 'gateway/watcher'
|
5
4
|
|
6
5
|
if Gem.loaded_specs['graphql'] && Gem.loaded_specs['graphql'].version >= Gem::Version.new('2.0.19')
|
@@ -13,8 +12,6 @@ module Datadog
|
|
13
12
|
module GraphQL
|
14
13
|
# Patcher for AppSec on GraphQL
|
15
14
|
module Patcher
|
16
|
-
include Datadog::AppSec::Contrib::Patcher
|
17
|
-
|
18
15
|
module_function
|
19
16
|
|
20
17
|
def patched?
|