datadog 2.10.0 → 2.12.2
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 +72 -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 +64 -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/instrumentation.rb +23 -6
- data/lib/datadog/appsec/contrib/active_record/patcher.rb +63 -15
- 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/ext.rb +20 -0
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +84 -72
- data/lib/datadog/appsec/contrib/rack/patcher.rb +0 -3
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +3 -0
- 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/rest_client/integration.rb +45 -0
- data/lib/datadog/appsec/contrib/rest_client/patcher.rb +28 -0
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +39 -0
- 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/instrumentation/gateway/middleware.rb +24 -0
- data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +19 -25
- data/lib/datadog/appsec/processor/rule_merger.rb +2 -1
- data/lib/datadog/appsec/remote.rb +11 -0
- data/lib/datadog/appsec.rb +3 -0
- data/lib/datadog/core/configuration/components.rb +17 -10
- 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/metrics/client.rb +9 -8
- data/lib/datadog/core/remote/client.rb +5 -4
- data/lib/datadog/core/remote/component.rb +14 -12
- data/lib/datadog/core/remote/negotiation.rb +1 -1
- 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 +6 -40
- data/lib/datadog/core/remote/transport/negotiation.rb +13 -1
- data/lib/datadog/core/remote/worker.rb +10 -7
- data/lib/datadog/core/telemetry/component.rb +5 -1
- data/lib/datadog/core/telemetry/event.rb +5 -0
- data/lib/datadog/core/telemetry/worker.rb +9 -5
- 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/http.rb +38 -0
- data/lib/datadog/core/transport/response.rb +4 -0
- data/lib/datadog/core/workers/runtime_metrics.rb +1 -1
- data/lib/datadog/di/code_tracker.rb +15 -8
- data/lib/datadog/di/component.rb +2 -3
- 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 +35 -8
- data/lib/datadog/di/remote.rb +3 -3
- data/lib/datadog/di/transport/diagnostics.rb +61 -0
- data/lib/datadog/di/transport/http/api.rb +52 -0
- data/lib/datadog/di/transport/http/client.rb +46 -0
- data/lib/datadog/di/transport/http/diagnostics.rb +92 -0
- data/lib/datadog/di/transport/http/input.rb +94 -0
- data/lib/datadog/di/transport/http.rb +105 -0
- data/lib/datadog/di/transport/input.rb +61 -0
- data/lib/datadog/di/utils.rb +91 -0
- data/lib/datadog/di.rb +5 -1
- data/lib/datadog/profiling/component.rb +2 -8
- data/lib/datadog/profiling/load_native_extension.rb +1 -33
- data/lib/datadog/tracing/component.rb +1 -0
- 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/metadata/metastruct.rb +36 -0
- data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
- data/lib/datadog/tracing/metadata.rb +2 -0
- data/lib/datadog/tracing/span.rb +10 -1
- data/lib/datadog/tracing/span_operation.rb +6 -1
- data/lib/datadog/tracing/sync_writer.rb +9 -4
- data/lib/datadog/tracing/tracer.rb +15 -7
- 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 +7 -31
- data/lib/datadog/tracing/transport/serializable_trace.rb +11 -5
- data/lib/datadog/tracing/transport/traces.rb +25 -8
- data/lib/datadog/tracing/workers/trace_writer.rb +10 -3
- data/lib/datadog/tracing/workers.rb +5 -4
- data/lib/datadog/tracing/writer.rb +12 -4
- data/lib/datadog/version.rb +2 -2
- metadata +37 -29
- 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
- data/lib/datadog/di/transport.rb +0 -79
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../patcher'
|
4
3
|
require_relative 'instrumentation'
|
5
4
|
|
6
5
|
module Datadog
|
@@ -9,8 +8,6 @@ module Datadog
|
|
9
8
|
module ActiveRecord
|
10
9
|
# AppSec patcher module for ActiveRecord
|
11
10
|
module Patcher
|
12
|
-
include Datadog::AppSec::Contrib::Patcher
|
13
|
-
|
14
11
|
module_function
|
15
12
|
|
16
13
|
def patched?
|
@@ -22,30 +19,81 @@ module Datadog
|
|
22
19
|
end
|
23
20
|
|
24
21
|
def patch
|
22
|
+
# Rails 7.0 intruduced new on-load hooks for sqlite3 and postgresql adapters
|
23
|
+
# The load hook for mysql2 adapter was introduced in Rails 7.1
|
24
|
+
#
|
25
|
+
# If the adapter is not loaded when the :active_record load hook is called,
|
26
|
+
# we need to add a load hook for the adapter
|
25
27
|
ActiveSupport.on_load :active_record do
|
26
|
-
instrumentation_module = if ::ActiveRecord.gem_version >= Gem::Version.new('7.1')
|
27
|
-
Instrumentation::InternalExecQueryAdapterPatch
|
28
|
-
else
|
29
|
-
Instrumentation::ExecQueryAdapterPatch
|
30
|
-
end
|
31
|
-
|
32
28
|
if defined?(::ActiveRecord::ConnectionAdapters::SQLite3Adapter)
|
33
|
-
::ActiveRecord::
|
29
|
+
::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_sqlite3_adapter
|
30
|
+
else
|
31
|
+
ActiveSupport.on_load :active_record_sqlite3adapter do
|
32
|
+
::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_sqlite3_adapter
|
33
|
+
end
|
34
34
|
end
|
35
35
|
|
36
36
|
if defined?(::ActiveRecord::ConnectionAdapters::Mysql2Adapter)
|
37
|
-
::ActiveRecord::
|
37
|
+
::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_mysql2_adapter
|
38
|
+
else
|
39
|
+
ActiveSupport.on_load :active_record_mysql2adapter do
|
40
|
+
::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_mysql2_adapter
|
41
|
+
end
|
38
42
|
end
|
39
43
|
|
40
44
|
if defined?(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
|
41
|
-
|
42
|
-
|
45
|
+
::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_postgresql_adapter
|
46
|
+
else
|
47
|
+
ActiveSupport.on_load :active_record_postgresqladapter do
|
48
|
+
::Datadog::AppSec::Contrib::ActiveRecord::Patcher.patch_postgresql_adapter
|
43
49
|
end
|
44
|
-
|
45
|
-
::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(instrumentation_module)
|
46
50
|
end
|
47
51
|
end
|
48
52
|
end
|
53
|
+
|
54
|
+
def patch_sqlite3_adapter
|
55
|
+
instrumentation_module = if ::ActiveRecord.gem_version >= Gem::Version.new('7.1')
|
56
|
+
Instrumentation::InternalExecQueryAdapterPatch
|
57
|
+
elsif ::ActiveRecord.gem_version.segments.first == 4
|
58
|
+
Instrumentation::Rails4ExecQueryAdapterPatch
|
59
|
+
else
|
60
|
+
Instrumentation::ExecQueryAdapterPatch
|
61
|
+
end
|
62
|
+
|
63
|
+
::ActiveRecord::ConnectionAdapters::SQLite3Adapter.prepend(instrumentation_module)
|
64
|
+
end
|
65
|
+
|
66
|
+
def patch_mysql2_adapter
|
67
|
+
instrumentation_module = if ::ActiveRecord.gem_version >= Gem::Version.new('7.1')
|
68
|
+
Instrumentation::InternalExecQueryAdapterPatch
|
69
|
+
elsif ::ActiveRecord.gem_version.segments.first == 4
|
70
|
+
Instrumentation::Rails4ExecQueryAdapterPatch
|
71
|
+
else
|
72
|
+
Instrumentation::ExecQueryAdapterPatch
|
73
|
+
end
|
74
|
+
|
75
|
+
::ActiveRecord::ConnectionAdapters::Mysql2Adapter.prepend(instrumentation_module)
|
76
|
+
end
|
77
|
+
|
78
|
+
def patch_postgresql_adapter
|
79
|
+
instrumentation_module = if ::ActiveRecord.gem_version.segments.first == 4
|
80
|
+
Instrumentation::Rails4ExecuteAndClearAdapterPatch
|
81
|
+
else
|
82
|
+
Instrumentation::ExecuteAndClearAdapterPatch
|
83
|
+
end
|
84
|
+
|
85
|
+
if defined?(::ActiveRecord::ConnectionAdapters::JdbcAdapter)
|
86
|
+
instrumentation_module = if ::ActiveRecord.gem_version >= Gem::Version.new('7.1')
|
87
|
+
Instrumentation::InternalExecQueryAdapterPatch
|
88
|
+
elsif ::ActiveRecord.gem_version.segments.first == 4
|
89
|
+
Instrumentation::Rails4ExecQueryAdapterPatch
|
90
|
+
else
|
91
|
+
Instrumentation::ExecQueryAdapterPatch
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(instrumentation_module)
|
96
|
+
end
|
49
97
|
end
|
50
98
|
end
|
51
99
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module AppSec
|
5
|
+
module Contrib
|
6
|
+
module Devise
|
7
|
+
# A temporary configuration module to accomodate new RFC changes.
|
8
|
+
# NOTE: DEV-3 Remove module
|
9
|
+
module Configuration
|
10
|
+
MODES_CONVERSION_RULES = {
|
11
|
+
track_user_to_auto_instrumentation: {
|
12
|
+
AppSec::Configuration::Settings::SAFE_TRACK_USER_EVENTS_MODE =>
|
13
|
+
AppSec::Configuration::Settings::ANONYMIZATION_AUTO_USER_INSTRUMENTATION_MODE,
|
14
|
+
AppSec::Configuration::Settings::EXTENDED_TRACK_USER_EVENTS_MODE =>
|
15
|
+
AppSec::Configuration::Settings::IDENTIFICATION_AUTO_USER_INSTRUMENTATION_MODE
|
16
|
+
}.freeze,
|
17
|
+
auto_instrumentation_to_track_user: {
|
18
|
+
AppSec::Configuration::Settings::ANONYMIZATION_AUTO_USER_INSTRUMENTATION_MODE =>
|
19
|
+
AppSec::Configuration::Settings::SAFE_TRACK_USER_EVENTS_MODE,
|
20
|
+
AppSec::Configuration::Settings::IDENTIFICATION_AUTO_USER_INSTRUMENTATION_MODE =>
|
21
|
+
AppSec::Configuration::Settings::EXTENDED_TRACK_USER_EVENTS_MODE
|
22
|
+
}.freeze
|
23
|
+
}.freeze
|
24
|
+
|
25
|
+
module_function
|
26
|
+
|
27
|
+
# NOTE: DEV-3 Replace method use with `auto_user_instrumentation.enabled?`
|
28
|
+
def auto_user_instrumentation_enabled?
|
29
|
+
appsec = Datadog.configuration.appsec
|
30
|
+
appsec.auto_user_instrumentation.mode
|
31
|
+
|
32
|
+
unless appsec.auto_user_instrumentation.options[:mode].default_precedence?
|
33
|
+
return appsec.auto_user_instrumentation.enabled?
|
34
|
+
end
|
35
|
+
|
36
|
+
appsec.track_user_events.enabled
|
37
|
+
end
|
38
|
+
|
39
|
+
# NOTE: DEV-3 Replace method use with `auto_user_instrumentation.mode`
|
40
|
+
def auto_user_instrumentation_mode
|
41
|
+
appsec = Datadog.configuration.appsec
|
42
|
+
|
43
|
+
# NOTE: Reading both to trigger precedence set
|
44
|
+
appsec.auto_user_instrumentation.mode
|
45
|
+
appsec.track_user_events.mode
|
46
|
+
|
47
|
+
if !appsec.auto_user_instrumentation.options[:mode].default_precedence? &&
|
48
|
+
appsec.track_user_events.options[:mode].default_precedence?
|
49
|
+
return appsec.auto_user_instrumentation.mode
|
50
|
+
end
|
51
|
+
|
52
|
+
if appsec.auto_user_instrumentation.options[:mode].default_precedence?
|
53
|
+
return MODES_CONVERSION_RULES[:track_user_to_auto_instrumentation].fetch(
|
54
|
+
appsec.track_user_events.mode, appsec.auto_user_instrumentation.mode
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
identification_mode = AppSec::Configuration::Settings::IDENTIFICATION_AUTO_USER_INSTRUMENTATION_MODE
|
59
|
+
if appsec.auto_user_instrumentation.mode == identification_mode ||
|
60
|
+
appsec.track_user_events.mode == AppSec::Configuration::Settings::EXTENDED_TRACK_USER_EVENTS_MODE
|
61
|
+
return identification_mode
|
62
|
+
end
|
63
|
+
|
64
|
+
AppSec::Configuration::Settings::ANONYMIZATION_AUTO_USER_INSTRUMENTATION_MODE
|
65
|
+
end
|
66
|
+
|
67
|
+
# NOTE: Remove in next version of tracking
|
68
|
+
def track_user_events_mode
|
69
|
+
MODES_CONVERSION_RULES[:auto_instrumentation_to_track_user]
|
70
|
+
.fetch(auto_user_instrumentation_mode, Datadog.configuration.appsec.track_user_events.mode)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -8,9 +8,6 @@ module Datadog
|
|
8
8
|
class Event
|
9
9
|
UUID_REGEX = /^\h{8}-\h{4}-\h{4}-\h{4}-\h{12}$/.freeze
|
10
10
|
|
11
|
-
SAFE_MODE = 'safe'
|
12
|
-
EXTENDED_MODE = 'extended'
|
13
|
-
|
14
11
|
attr_reader :user_id
|
15
12
|
|
16
13
|
def initialize(resource, mode)
|
@@ -38,15 +35,15 @@ module Datadog
|
|
38
35
|
@user_id = @resource.id
|
39
36
|
|
40
37
|
case @mode
|
41
|
-
when
|
38
|
+
when AppSec::Configuration::Settings::IDENTIFICATION_AUTO_USER_INSTRUMENTATION_MODE
|
42
39
|
@email = @resource.email
|
43
40
|
@username = @resource.username
|
44
|
-
when
|
41
|
+
when AppSec::Configuration::Settings::ANONYMIZATION_AUTO_USER_INSTRUMENTATION_MODE
|
45
42
|
@user_id = nil unless @user_id && @user_id.to_s =~ UUID_REGEX
|
46
43
|
else
|
47
44
|
Datadog.logger.warn(
|
48
|
-
"Invalid
|
49
|
-
|
45
|
+
"Invalid auto_user_instrumentation.mode: `#{@mode}`. " \
|
46
|
+
"Supported modes are: #{AppSec::Configuration::Settings::AUTO_USER_INSTRUMENTATION_MODES.join(' | ')}."
|
50
47
|
)
|
51
48
|
end
|
52
49
|
end
|
@@ -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
|