datadog 2.7.1 → 2.17.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 +310 -1
- data/ext/datadog_profiling_native_extension/clock_id.h +2 -2
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +66 -56
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +1 -1
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +16 -16
- data/ext/datadog_profiling_native_extension/collectors_stack.c +10 -10
- data/ext/datadog_profiling_native_extension/collectors_stack.h +2 -2
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +314 -145
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
- data/ext/datadog_profiling_native_extension/encoded_profile.c +79 -0
- data/ext/datadog_profiling_native_extension/encoded_profile.h +8 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +7 -8
- 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 +61 -174
- data/ext/datadog_profiling_native_extension/heap_recorder.h +2 -2
- data/ext/datadog_profiling_native_extension/http_transport.c +64 -98
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +68 -1
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +10 -1
- data/ext/datadog_profiling_native_extension/profiling.c +19 -8
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +8 -8
- data/ext/datadog_profiling_native_extension/stack_recorder.c +84 -131
- data/ext/datadog_profiling_native_extension/stack_recorder.h +2 -2
- data/ext/datadog_profiling_native_extension/time_helpers.h +1 -1
- data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.c +47 -0
- data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +31 -0
- data/ext/libdatadog_api/crashtracker.c +17 -15
- data/ext/libdatadog_api/crashtracker.h +5 -0
- data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
- data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
- data/ext/libdatadog_api/init.c +15 -0
- data/ext/libdatadog_api/library_config.c +122 -0
- data/ext/libdatadog_api/library_config.h +19 -0
- data/ext/libdatadog_api/macos_development.md +3 -3
- data/ext/libdatadog_api/process_discovery.c +117 -0
- data/ext/libdatadog_api/process_discovery.h +5 -0
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
- data/lib/datadog/appsec/actions_handler.rb +49 -0
- data/lib/datadog/appsec/anonymizer.rb +16 -0
- data/lib/datadog/appsec/api_security/lru_cache.rb +49 -0
- data/lib/datadog/appsec/api_security.rb +9 -0
- data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
- data/lib/datadog/appsec/assets/waf_rules/processors.json +239 -10
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +355 -157
- data/lib/datadog/appsec/assets/waf_rules/scanners.json +926 -17
- data/lib/datadog/appsec/assets/waf_rules/strict.json +62 -32
- data/lib/datadog/appsec/autoload.rb +1 -1
- data/lib/datadog/appsec/component.rb +41 -33
- data/lib/datadog/appsec/compressed_json.rb +40 -0
- data/lib/datadog/appsec/configuration/settings.rb +152 -25
- data/lib/datadog/appsec/context.rb +74 -0
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +92 -0
- data/lib/datadog/appsec/contrib/active_record/integration.rb +41 -0
- data/lib/datadog/appsec/contrib/active_record/patcher.rb +101 -0
- data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/configuration.rb +52 -0
- data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
- data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
- data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
- data/lib/datadog/appsec/contrib/devise/patcher.rb +33 -25
- data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
- data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
- data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +3 -3
- data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
- 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 +42 -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 +41 -0
- data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +1 -7
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +17 -30
- data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/graphql/patcher.rb +0 -3
- data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
- data/lib/datadog/appsec/contrib/rack/gateway/response.rb +3 -3
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +78 -98
- data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/patcher.rb +0 -3
- data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +10 -11
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +52 -68
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +16 -33
- data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/patcher.rb +25 -38
- 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 +38 -0
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +31 -68
- data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +5 -31
- data/lib/datadog/appsec/event.rb +96 -135
- data/lib/datadog/appsec/ext.rb +12 -3
- data/lib/datadog/appsec/instrumentation/gateway/argument.rb +7 -2
- data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
- data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
- data/lib/datadog/appsec/metrics/collector.rb +38 -0
- data/lib/datadog/appsec/metrics/exporter.rb +35 -0
- data/lib/datadog/appsec/metrics/telemetry.rb +23 -0
- data/lib/datadog/appsec/metrics.rb +13 -0
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +52 -32
- data/lib/datadog/appsec/processor/rule_loader.rb +26 -31
- data/lib/datadog/appsec/processor/rule_merger.rb +7 -6
- data/lib/datadog/appsec/processor.rb +5 -4
- data/lib/datadog/appsec/remote.rb +26 -12
- data/lib/datadog/appsec/response.rb +19 -85
- data/lib/datadog/appsec/security_engine/result.rb +67 -0
- data/lib/datadog/appsec/security_engine/runner.rb +88 -0
- data/lib/datadog/appsec/security_engine.rb +9 -0
- data/lib/datadog/appsec/security_event.rb +39 -0
- data/lib/datadog/appsec/utils.rb +0 -2
- data/lib/datadog/appsec.rb +23 -10
- data/lib/datadog/auto_instrument.rb +3 -0
- data/lib/datadog/core/buffer/random.rb +18 -2
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +42 -14
- data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
- data/lib/datadog/core/configuration/components.rb +76 -32
- data/lib/datadog/core/configuration/components_state.rb +23 -0
- data/lib/datadog/core/configuration/ext.rb +5 -1
- data/lib/datadog/core/configuration/option.rb +79 -43
- data/lib/datadog/core/configuration/option_definition.rb +6 -4
- data/lib/datadog/core/configuration/options.rb +3 -3
- data/lib/datadog/core/configuration/settings.rb +100 -41
- data/lib/datadog/core/configuration/stable_config.rb +23 -0
- data/lib/datadog/core/configuration.rb +43 -11
- data/lib/datadog/{tracing → core}/contrib/rails/utils.rb +1 -3
- data/lib/datadog/core/crashtracking/component.rb +4 -13
- data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
- data/lib/datadog/core/encoding.rb +17 -1
- data/lib/datadog/core/environment/agent_info.rb +78 -0
- data/lib/datadog/core/environment/cgroup.rb +10 -12
- data/lib/datadog/core/environment/container.rb +38 -40
- data/lib/datadog/core/environment/ext.rb +6 -6
- data/lib/datadog/core/environment/git.rb +1 -0
- data/lib/datadog/core/environment/identity.rb +3 -3
- data/lib/datadog/core/environment/platform.rb +3 -3
- data/lib/datadog/core/environment/variable_helpers.rb +1 -1
- data/lib/datadog/core/error.rb +11 -9
- data/lib/datadog/core/logger.rb +2 -2
- data/lib/datadog/core/metrics/client.rb +27 -27
- data/lib/datadog/core/metrics/logging.rb +5 -5
- data/lib/datadog/core/process_discovery.rb +32 -0
- data/lib/datadog/core/rate_limiter.rb +4 -2
- data/lib/datadog/core/remote/client/capabilities.rb +6 -0
- data/lib/datadog/core/remote/client.rb +107 -92
- data/lib/datadog/core/remote/component.rb +18 -19
- data/lib/datadog/core/remote/configuration/digest.rb +7 -7
- data/lib/datadog/core/remote/configuration/path.rb +1 -1
- data/lib/datadog/core/remote/configuration/repository.rb +2 -1
- data/lib/datadog/core/remote/negotiation.rb +9 -9
- data/lib/datadog/core/remote/transport/config.rb +4 -3
- data/lib/datadog/core/remote/transport/http/api.rb +13 -18
- data/lib/datadog/core/remote/transport/http/client.rb +5 -4
- data/lib/datadog/core/remote/transport/http/config.rb +27 -55
- data/lib/datadog/core/remote/transport/http/negotiation.rb +8 -51
- data/lib/datadog/core/remote/transport/http.rb +25 -94
- data/lib/datadog/core/remote/transport/negotiation.rb +17 -4
- data/lib/datadog/core/remote/worker.rb +10 -7
- data/lib/datadog/core/runtime/metrics.rb +12 -5
- data/lib/datadog/core/telemetry/component.rb +84 -49
- data/lib/datadog/core/telemetry/emitter.rb +23 -11
- data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +65 -0
- data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
- data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
- data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
- data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
- data/lib/datadog/core/telemetry/event/app_started.rb +179 -0
- data/lib/datadog/core/telemetry/event/base.rb +40 -0
- data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
- data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
- data/lib/datadog/core/telemetry/event/log.rb +76 -0
- data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
- data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
- data/lib/datadog/core/telemetry/event.rb +17 -383
- data/lib/datadog/core/telemetry/ext.rb +1 -0
- data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
- data/lib/datadog/core/telemetry/logger.rb +1 -1
- data/lib/datadog/core/telemetry/logging.rb +2 -2
- data/lib/datadog/core/telemetry/metric.rb +28 -6
- data/lib/datadog/core/telemetry/request.rb +4 -4
- data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
- data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
- data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
- data/lib/datadog/core/telemetry/transport/http.rb +63 -0
- data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
- data/lib/datadog/core/telemetry/worker.rb +128 -25
- data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
- data/lib/datadog/core/transport/http/adapters/unix_socket.rb +1 -1
- data/lib/datadog/{tracing → core}/transport/http/api/instance.rb +18 -1
- data/lib/datadog/core/transport/http/api/spec.rb +36 -0
- data/lib/datadog/{tracing → core}/transport/http/builder.rb +53 -31
- data/lib/datadog/core/transport/http.rb +75 -0
- data/lib/datadog/core/transport/response.rb +4 -0
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
- data/lib/datadog/core/utils/duration.rb +32 -32
- data/lib/datadog/core/utils/forking.rb +2 -2
- data/lib/datadog/core/utils/network.rb +6 -6
- data/lib/datadog/core/utils/only_once_successful.rb +16 -5
- data/lib/datadog/core/utils/time.rb +20 -0
- data/lib/datadog/core/utils/truncation.rb +21 -0
- data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
- data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
- data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
- data/lib/datadog/core/worker.rb +1 -1
- data/lib/datadog/core/workers/async.rb +29 -12
- data/lib/datadog/core/workers/interval_loop.rb +12 -1
- data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
- data/lib/datadog/core.rb +8 -0
- data/lib/datadog/di/base.rb +115 -0
- data/lib/datadog/di/boot.rb +34 -0
- data/lib/datadog/di/code_tracker.rb +26 -15
- data/lib/datadog/di/component.rb +23 -14
- data/lib/datadog/di/configuration/settings.rb +25 -1
- data/lib/datadog/di/contrib/active_record.rb +1 -0
- data/lib/datadog/di/contrib/railtie.rb +15 -0
- data/lib/datadog/di/contrib.rb +28 -0
- data/lib/datadog/di/error.rb +5 -0
- data/lib/datadog/di/instrumenter.rb +111 -20
- data/lib/datadog/di/logger.rb +30 -0
- data/lib/datadog/di/preload.rb +18 -0
- data/lib/datadog/di/probe.rb +14 -7
- data/lib/datadog/di/probe_builder.rb +1 -0
- data/lib/datadog/di/probe_manager.rb +11 -5
- data/lib/datadog/di/probe_notification_builder.rb +34 -8
- data/lib/datadog/di/probe_notifier_worker.rb +52 -26
- data/lib/datadog/di/redactor.rb +0 -1
- data/lib/datadog/di/remote.rb +147 -0
- data/lib/datadog/di/serializer.rb +14 -7
- data/lib/datadog/di/transport/diagnostics.rb +62 -0
- data/lib/datadog/di/transport/http/api.rb +42 -0
- data/lib/datadog/di/transport/http/client.rb +47 -0
- data/lib/datadog/di/transport/http/diagnostics.rb +65 -0
- data/lib/datadog/di/transport/http/input.rb +67 -0
- data/lib/datadog/di/transport/http.rb +57 -0
- data/lib/datadog/di/transport/input.rb +62 -0
- data/lib/datadog/di/utils.rb +103 -0
- data/lib/datadog/di.rb +14 -76
- data/lib/datadog/error_tracking/collector.rb +87 -0
- data/lib/datadog/error_tracking/component.rb +167 -0
- data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
- data/lib/datadog/error_tracking/configuration.rb +11 -0
- data/lib/datadog/error_tracking/ext.rb +18 -0
- data/lib/datadog/error_tracking/extensions.rb +16 -0
- data/lib/datadog/error_tracking/filters.rb +77 -0
- data/lib/datadog/error_tracking.rb +18 -0
- data/lib/datadog/kit/appsec/events.rb +15 -3
- data/lib/datadog/kit/identity.rb +9 -5
- data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
- data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
- data/lib/datadog/opentelemetry/api/context.rb +16 -2
- data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
- data/lib/datadog/opentelemetry.rb +2 -1
- data/lib/datadog/profiling/collectors/code_provenance.rb +1 -1
- data/lib/datadog/profiling/collectors/info.rb +3 -0
- data/lib/datadog/profiling/collectors/thread_context.rb +1 -1
- data/lib/datadog/profiling/component.rb +60 -76
- data/lib/datadog/profiling/encoded_profile.rb +11 -0
- data/lib/datadog/profiling/exporter.rb +3 -4
- data/lib/datadog/profiling/ext.rb +0 -2
- data/lib/datadog/profiling/flush.rb +5 -8
- data/lib/datadog/profiling/http_transport.rb +6 -85
- data/lib/datadog/profiling/load_native_extension.rb +1 -33
- data/lib/datadog/profiling/scheduler.rb +8 -1
- data/lib/datadog/profiling/stack_recorder.rb +4 -4
- data/lib/datadog/profiling/tag_builder.rb +1 -5
- data/lib/datadog/profiling.rb +6 -2
- data/lib/datadog/tracing/analytics.rb +1 -1
- data/lib/datadog/tracing/component.rb +16 -12
- data/lib/datadog/tracing/configuration/ext.rb +8 -1
- data/lib/datadog/tracing/configuration/settings.rb +22 -10
- data/lib/datadog/tracing/context_provider.rb +1 -1
- data/lib/datadog/tracing/contrib/action_cable/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/action_mailer/integration.rb +6 -2
- data/lib/datadog/tracing/contrib/action_pack/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/action_view/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/active_job/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/active_record/integration.rb +7 -3
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +7 -2
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +36 -1
- data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
- data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +14 -4
- data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +10 -0
- data/lib/datadog/tracing/contrib/active_support/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/auto_instrument.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
- data/lib/datadog/tracing/contrib/aws/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
- data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +4 -0
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
- data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
- data/lib/datadog/tracing/contrib/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/extensions.rb +29 -3
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
- 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/grpc/datadog_interceptor/client.rb +7 -1
- data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
- data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
- data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -10
- data/lib/datadog/tracing/contrib/http/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -16
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
- data/lib/datadog/tracing/contrib/httprb/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/kafka/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
- data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
- data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
- data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
- data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
- data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
- data/lib/datadog/tracing/contrib/karafka.rb +37 -0
- data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
- data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mongodb/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
- data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
- data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
- data/lib/datadog/tracing/contrib/opensearch/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
- data/lib/datadog/tracing/contrib/patcher.rb +5 -2
- data/lib/datadog/tracing/contrib/presto/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/rack/header_collection.rb +11 -1
- data/lib/datadog/tracing/contrib/rack/integration.rb +2 -2
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +1 -1
- data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/framework.rb +2 -2
- data/lib/datadog/tracing/contrib/rails/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/rest_client/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
- data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
- data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
- data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +1 -1
- data/lib/datadog/tracing/contrib/span_attribute_schema.rb +6 -1
- data/lib/datadog/tracing/contrib/support.rb +28 -0
- data/lib/datadog/tracing/contrib.rb +1 -0
- data/lib/datadog/tracing/correlation.rb +9 -2
- data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
- data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
- data/lib/datadog/tracing/distributed/baggage.rb +131 -0
- data/lib/datadog/tracing/distributed/datadog.rb +4 -2
- data/lib/datadog/tracing/distributed/propagation.rb +25 -4
- data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
- data/lib/datadog/tracing/metadata/errors.rb +4 -4
- data/lib/datadog/tracing/metadata/ext.rb +5 -0
- 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/sampling/rate_sampler.rb +2 -1
- data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
- data/lib/datadog/tracing/span.rb +22 -5
- data/lib/datadog/tracing/span_event.rb +124 -4
- data/lib/datadog/tracing/span_operation.rb +52 -16
- data/lib/datadog/tracing/sync_writer.rb +9 -5
- data/lib/datadog/tracing/trace_digest.rb +9 -2
- data/lib/datadog/tracing/trace_operation.rb +44 -24
- data/lib/datadog/tracing/trace_segment.rb +6 -4
- data/lib/datadog/tracing/tracer.rb +60 -12
- data/lib/datadog/tracing/transport/http/api.rb +5 -4
- data/lib/datadog/tracing/transport/http/client.rb +5 -4
- data/lib/datadog/tracing/transport/http/traces.rb +13 -44
- data/lib/datadog/tracing/transport/http.rb +13 -70
- data/lib/datadog/tracing/transport/serializable_trace.rb +31 -7
- data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
- data/lib/datadog/tracing/transport/traces.rb +47 -13
- data/lib/datadog/tracing/utils.rb +1 -1
- data/lib/datadog/tracing/workers/trace_writer.rb +8 -5
- data/lib/datadog/tracing/workers.rb +5 -4
- data/lib/datadog/tracing/writer.rb +10 -6
- data/lib/datadog/tracing.rb +16 -3
- data/lib/datadog/version.rb +2 -2
- data/lib/datadog.rb +2 -0
- metadata +143 -50
- 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/devise/event.rb +0 -57
- data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -77
- data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -54
- data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
- data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
- 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/ext.rb +0 -14
- 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/processor/actions.rb +0 -49
- data/lib/datadog/appsec/processor/context.rb +0 -107
- data/lib/datadog/appsec/reactive/address_hash.rb +0 -22
- data/lib/datadog/appsec/reactive/engine.rb +0 -47
- data/lib/datadog/appsec/reactive/operation.rb +0 -68
- data/lib/datadog/appsec/reactive/subscriber.rb +0 -19
- data/lib/datadog/appsec/scope.rb +0 -58
- data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
- data/lib/datadog/core/crashtracking/agent_base_url.rb +0 -21
- 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/core/telemetry/http/env.rb +0 -20
- data/lib/datadog/core/telemetry/http/ext.rb +0 -28
- data/lib/datadog/core/telemetry/http/response.rb +0 -70
- data/lib/datadog/core/telemetry/http/transport.rb +0 -90
- data/lib/datadog/di/transport.rb +0 -81
- data/lib/datadog/tracing/transport/http/api/spec.rb +0 -19
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../../event'
|
4
|
+
require_relative '../../security_event'
|
3
5
|
require_relative '../../instrumentation/gateway'
|
4
|
-
require_relative '../../reactive/operation'
|
5
|
-
require_relative '../reactive/set_user'
|
6
6
|
|
7
7
|
module Datadog
|
8
8
|
module AppSec
|
@@ -10,51 +10,71 @@ module Datadog
|
|
10
10
|
module Gateway
|
11
11
|
# Watcher for Apssec internal events
|
12
12
|
module Watcher
|
13
|
+
ARBITRARY_VALUE = 'invalid'
|
14
|
+
EVENT_LOGIN_SUCCESS = 'users.login.success'
|
15
|
+
EVENT_LOGIN_FAILURE = 'users.login.failure'
|
16
|
+
WATCHED_LOGIN_EVENTS = [EVENT_LOGIN_SUCCESS, EVENT_LOGIN_FAILURE].freeze
|
17
|
+
|
13
18
|
class << self
|
14
19
|
def watch
|
15
20
|
gateway = Instrumentation.gateway
|
16
21
|
|
17
22
|
watch_user_id(gateway)
|
23
|
+
watch_user_login(gateway)
|
18
24
|
end
|
19
25
|
|
20
26
|
def watch_user_id(gateway = Instrumentation.gateway)
|
21
27
|
gateway.watch('identity.set_user', :appsec) do |stack, user|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
block = Monitor::Reactive::SetUser.publish(op, user)
|
28
|
+
context = AppSec.active_context
|
29
|
+
|
30
|
+
if user.id.nil? && user.login.nil? && user.session_id.nil?
|
31
|
+
Datadog.logger.debug { 'AppSec: skipping WAF check because no user information was provided' }
|
32
|
+
next stack.call(user)
|
33
|
+
end
|
34
|
+
|
35
|
+
persistent_data = {}
|
36
|
+
persistent_data['usr.id'] = user.id if user.id
|
37
|
+
persistent_data['usr.login'] = user.login if user.login
|
38
|
+
persistent_data['usr.session_id'] = user.session_id if user.session_id
|
39
|
+
|
40
|
+
result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
|
41
|
+
|
42
|
+
if result.match? || result.derivatives.any?
|
43
|
+
context.events.push(
|
44
|
+
AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
if result.match?
|
49
|
+
AppSec::Event.tag_and_keep!(context, result)
|
50
|
+
AppSec::ActionsHandler.handle(result.actions)
|
46
51
|
end
|
47
52
|
|
48
|
-
|
53
|
+
stack.call(user)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def watch_user_login(gateway = Instrumentation.gateway)
|
58
|
+
gateway.watch('appsec.events.user_lifecycle', :appsec) do |stack, kind|
|
59
|
+
context = AppSec.active_context
|
49
60
|
|
50
|
-
|
61
|
+
next stack.call(kind) unless WATCHED_LOGIN_EVENTS.include?(kind)
|
62
|
+
|
63
|
+
persistent_data = {"server.business_logic.#{kind}" => ARBITRARY_VALUE}
|
64
|
+
result = context.run_waf(persistent_data, {}, Datadog.configuration.appsec.waf_timeout)
|
65
|
+
|
66
|
+
if result.match? || result.derivatives.any?
|
67
|
+
context.events.push(
|
68
|
+
AppSec::SecurityEvent.new(result, trace: context.trace, span: context.span)
|
69
|
+
)
|
70
|
+
end
|
51
71
|
|
52
|
-
if
|
53
|
-
|
54
|
-
|
72
|
+
if result.match?
|
73
|
+
AppSec::Event.tag_and_keep!(context, result)
|
74
|
+
AppSec::ActionsHandler.handle(result.actions)
|
55
75
|
end
|
56
76
|
|
57
|
-
|
77
|
+
stack.call(kind)
|
58
78
|
end
|
59
79
|
end
|
60
80
|
end
|
@@ -10,35 +10,33 @@ module Datadog
|
|
10
10
|
module RuleLoader
|
11
11
|
class << self
|
12
12
|
def load_rules(ruleset:, telemetry:)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
13
|
+
case ruleset
|
14
|
+
when :recommended, :strict
|
15
|
+
JSON.parse(Datadog::AppSec::Assets.waf_rules(ruleset))
|
16
|
+
when :risky
|
17
|
+
Datadog.logger.warn(
|
18
|
+
'The :risky Application Security Management ruleset has been deprecated and no longer available.' \
|
19
|
+
'The `:recommended` ruleset will be used instead.' \
|
20
|
+
'Please remove the `appsec.ruleset = :risky` setting from your Datadog.configure block.'
|
21
|
+
)
|
22
|
+
JSON.parse(Datadog::AppSec::Assets.waf_rules(:recommended))
|
23
|
+
when String
|
24
|
+
JSON.parse(File.read(File.expand_path(ruleset)))
|
25
|
+
when File, StringIO
|
26
|
+
JSON.parse(ruleset.read || '').tap { ruleset.rewind }
|
27
|
+
when Hash
|
28
|
+
ruleset
|
29
|
+
else
|
30
|
+
raise ArgumentError, "unsupported value for ruleset setting: #{ruleset.inspect}"
|
31
|
+
end
|
32
|
+
rescue => e
|
33
|
+
Datadog.logger.error do
|
34
|
+
"libddwaf ruleset failed to load, ruleset: #{ruleset.inspect} error: #{e.inspect}"
|
35
|
+
end
|
37
36
|
|
38
|
-
|
37
|
+
telemetry.report(e, description: 'libddwaf ruleset failed to load')
|
39
38
|
|
40
|
-
|
41
|
-
end
|
39
|
+
nil
|
42
40
|
end
|
43
41
|
|
44
42
|
def load_data(ip_denylist: [], user_id_denylist: [])
|
@@ -62,7 +60,7 @@ module Datadog
|
|
62
60
|
{
|
63
61
|
'id' => id,
|
64
62
|
'type' => 'data_with_expiration',
|
65
|
-
'data' => denylist.map { |v| {
|
63
|
+
'data' => denylist.map { |v| {'value' => v.to_s, 'expiration' => 2**63} }
|
66
64
|
}
|
67
65
|
end
|
68
66
|
|
@@ -74,9 +72,6 @@ module Datadog
|
|
74
72
|
when Hash
|
75
73
|
pass = ip_passlist[:pass]
|
76
74
|
monitor = ip_passlist[:monitor]
|
77
|
-
else
|
78
|
-
pass = []
|
79
|
-
monitor = []
|
80
75
|
end
|
81
76
|
|
82
77
|
exclusions = []
|
@@ -11,8 +11,8 @@ module Datadog
|
|
11
11
|
# RuleVersionMismatchError
|
12
12
|
class RuleVersionMismatchError < StandardError
|
13
13
|
def initialize(version1, version2)
|
14
|
-
msg = 'Merging rule files with different version could lead to unkown behaviour. '\
|
15
|
-
"We have receieve two rule files with versions: #{version1}, #{version2}. "\
|
14
|
+
msg = 'Merging rule files with different version could lead to unkown behaviour. ' \
|
15
|
+
"We have receieve two rule files with versions: #{version1}, #{version2}. " \
|
16
16
|
'Please validate the configuration is correct and try again.'
|
17
17
|
super(msg)
|
18
18
|
end
|
@@ -22,12 +22,12 @@ module Datadog
|
|
22
22
|
# TODO: `processors` and `scanners` are not provided by the caller, consider removing them
|
23
23
|
def merge(
|
24
24
|
telemetry:,
|
25
|
-
rules:, data: [], overrides: [], exclusions: [], custom_rules: [],
|
25
|
+
rules:, actions: [], data: [], overrides: [], exclusions: [], custom_rules: [],
|
26
26
|
processors: nil, scanners: nil
|
27
27
|
)
|
28
28
|
processors ||= begin
|
29
29
|
default_waf_processors
|
30
|
-
rescue
|
30
|
+
rescue => e
|
31
31
|
Datadog.logger.error("libddwaf rulemerger failed to parse default waf processors. Error: #{e.inspect}")
|
32
32
|
telemetry.report(
|
33
33
|
e,
|
@@ -38,7 +38,7 @@ module Datadog
|
|
38
38
|
|
39
39
|
scanners ||= begin
|
40
40
|
default_waf_scanners
|
41
|
-
rescue
|
41
|
+
rescue => e
|
42
42
|
Datadog.logger.error("libddwaf rulemerger failed to parse default waf scanners. Error: #{e.inspect}")
|
43
43
|
telemetry.report(
|
44
44
|
e,
|
@@ -54,6 +54,7 @@ module Datadog
|
|
54
54
|
combined_exclusions = combine_exclusions(exclusions) if exclusions.any?
|
55
55
|
combined_custom_rules = combine_custom_rules(custom_rules) if custom_rules.any?
|
56
56
|
|
57
|
+
combined_rules['actions'] = actions if actions.any?
|
57
58
|
combined_rules['rules_data'] = combined_data if combined_data
|
58
59
|
combined_rules['rules_override'] = combined_overrides if combined_overrides
|
59
60
|
combined_rules['exclusions'] = combined_exclusions if combined_exclusions
|
@@ -145,7 +146,7 @@ module Datadog
|
|
145
146
|
end
|
146
147
|
|
147
148
|
result.each_with_object([]) do |entry, acc|
|
148
|
-
value = {
|
149
|
+
value = {'value' => entry[0]}
|
149
150
|
value['expiration'] = entry[1] if entry[1]
|
150
151
|
|
151
152
|
acc << value
|
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
3
|
+
require_relative 'security_engine/runner'
|
4
4
|
|
5
5
|
module Datadog
|
6
6
|
module AppSec
|
7
7
|
# Processor integrates libddwaf into datadog/appsec
|
8
|
+
# NOTE: This class will be moved under AppSec::SecurityEngine namespace
|
8
9
|
class Processor
|
9
10
|
attr_reader :diagnostics, :addresses
|
10
11
|
|
@@ -29,8 +30,8 @@ module Datadog
|
|
29
30
|
@handle.finalize
|
30
31
|
end
|
31
32
|
|
32
|
-
def
|
33
|
-
|
33
|
+
def new_runner
|
34
|
+
SecurityEngine::Runner.new(@handle, telemetry: @telemetry)
|
34
35
|
end
|
35
36
|
|
36
37
|
private
|
@@ -81,7 +82,7 @@ module Datadog
|
|
81
82
|
@diagnostics = e.diagnostics if e.diagnostics
|
82
83
|
|
83
84
|
false
|
84
|
-
rescue
|
85
|
+
rescue => e
|
85
86
|
Datadog.logger.error do
|
86
87
|
"libddwaf failed to initialize, error: #{e.inspect}"
|
87
88
|
end
|
@@ -9,20 +9,23 @@ module Datadog
|
|
9
9
|
# Remote
|
10
10
|
module Remote
|
11
11
|
class ReadError < StandardError; end
|
12
|
+
|
12
13
|
class NoRulesError < StandardError; end
|
13
14
|
|
14
15
|
class << self
|
15
|
-
CAP_ASM_RESERVED_1
|
16
|
-
CAP_ASM_ACTIVATION
|
17
|
-
CAP_ASM_IP_BLOCKING
|
18
|
-
CAP_ASM_DD_RULES
|
19
|
-
CAP_ASM_EXCLUSIONS
|
20
|
-
CAP_ASM_REQUEST_BLOCKING
|
21
|
-
CAP_ASM_RESPONSE_BLOCKING
|
22
|
-
CAP_ASM_USER_BLOCKING
|
23
|
-
CAP_ASM_CUSTOM_RULES
|
24
|
-
CAP_ASM_CUSTOM_BLOCKING_RESPONSE
|
25
|
-
CAP_ASM_TRUSTED_IPS
|
16
|
+
CAP_ASM_RESERVED_1 = 1 << 0 # RESERVED
|
17
|
+
CAP_ASM_ACTIVATION = 1 << 1 # Remote activation via ASM_FEATURES product
|
18
|
+
CAP_ASM_IP_BLOCKING = 1 << 2 # accept IP blocking data from ASM_DATA product
|
19
|
+
CAP_ASM_DD_RULES = 1 << 3 # read ASM rules from ASM_DD product
|
20
|
+
CAP_ASM_EXCLUSIONS = 1 << 4 # exclusion filters (passlist) via ASM product
|
21
|
+
CAP_ASM_REQUEST_BLOCKING = 1 << 5 # can block on request info
|
22
|
+
CAP_ASM_RESPONSE_BLOCKING = 1 << 6 # can block on response info
|
23
|
+
CAP_ASM_USER_BLOCKING = 1 << 7 # accept user blocking data from ASM_DATA product
|
24
|
+
CAP_ASM_CUSTOM_RULES = 1 << 8 # accept custom rules
|
25
|
+
CAP_ASM_CUSTOM_BLOCKING_RESPONSE = 1 << 9 # supports custom http code or redirect sa blocking response
|
26
|
+
CAP_ASM_TRUSTED_IPS = 1 << 10 # supports trusted ip
|
27
|
+
CAP_ASM_RASP_SSRF = 1 << 23 # support for server-side request forgery exploit prevention rules
|
28
|
+
CAP_ASM_RASP_SQLI = 1 << 21 # support for SQL injection exploit prevention rules
|
26
29
|
|
27
30
|
# TODO: we need to dynamically add CAP_ASM_ACTIVATION once we support it
|
28
31
|
ASM_CAPABILITIES = [
|
@@ -35,6 +38,8 @@ module Datadog
|
|
35
38
|
CAP_ASM_CUSTOM_RULES,
|
36
39
|
CAP_ASM_CUSTOM_BLOCKING_RESPONSE,
|
37
40
|
CAP_ASM_TRUSTED_IPS,
|
41
|
+
CAP_ASM_RASP_SSRF,
|
42
|
+
CAP_ASM_RASP_SQLI,
|
38
43
|
].freeze
|
39
44
|
|
40
45
|
ASM_PRODUCTS = [
|
@@ -53,10 +58,12 @@ module Datadog
|
|
53
58
|
end
|
54
59
|
|
55
60
|
# rubocop:disable Metrics/MethodLength
|
61
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
56
62
|
def receivers(telemetry)
|
57
63
|
return [] unless remote_features_enabled?
|
58
64
|
|
59
65
|
matcher = Core::Remote::Dispatcher::Matcher::Product.new(ASM_PRODUCTS)
|
66
|
+
# rubocop:disable Metrics/BlockLength
|
60
67
|
receiver = Core::Remote::Dispatcher::Receiver.new(matcher) do |repository, changes|
|
61
68
|
changes.each do |change|
|
62
69
|
Datadog.logger.debug { "remote config change: '#{change.path}'" }
|
@@ -99,18 +106,25 @@ module Datadog
|
|
99
106
|
ruleset = AppSec::Processor::RuleMerger.merge(
|
100
107
|
rules: rules,
|
101
108
|
data: data,
|
109
|
+
actions: actions,
|
102
110
|
overrides: overrides,
|
103
111
|
exclusions: exclusions,
|
104
112
|
custom_rules: custom_rules,
|
105
113
|
telemetry: telemetry
|
106
114
|
)
|
107
115
|
|
108
|
-
Datadog::AppSec.reconfigure(ruleset: ruleset,
|
116
|
+
Datadog::AppSec.reconfigure(ruleset: ruleset, telemetry: telemetry)
|
117
|
+
|
118
|
+
repository.contents.each do |content|
|
119
|
+
content.applied if ASM_PRODUCTS.include?(content.path.product)
|
120
|
+
end
|
109
121
|
end
|
122
|
+
# rubocop:enable Metrics/BlockLength
|
110
123
|
|
111
124
|
[receiver]
|
112
125
|
end
|
113
126
|
# rubocop:enable Metrics/MethodLength
|
127
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
114
128
|
|
115
129
|
private
|
116
130
|
|
@@ -19,104 +19,38 @@ module Datadog
|
|
19
19
|
[status, headers, body]
|
20
20
|
end
|
21
21
|
|
22
|
-
def to_sinatra_response
|
23
|
-
::Sinatra::Response.new(body, status, headers)
|
24
|
-
end
|
25
|
-
|
26
|
-
def to_action_dispatch_response
|
27
|
-
::ActionDispatch::Response.new(status, headers, body)
|
28
|
-
end
|
29
|
-
|
30
22
|
class << self
|
31
|
-
def
|
32
|
-
|
33
|
-
configured_response = nil
|
34
|
-
actions.each do |action|
|
35
|
-
# Need to use next to make steep happy :(
|
36
|
-
# I rather use break to stop the execution
|
37
|
-
next if configured_response
|
38
|
-
|
39
|
-
action_configuration = AppSec::Processor::Actions.fetch_configuration(action)
|
40
|
-
next unless action_configuration
|
41
|
-
|
42
|
-
configured_response = case action_configuration['type']
|
43
|
-
when 'block_request'
|
44
|
-
block_response(env, action_configuration['parameters'])
|
45
|
-
when 'redirect_request'
|
46
|
-
redirect_response(env, action_configuration['parameters'])
|
47
|
-
end
|
48
|
-
end
|
23
|
+
def from_interrupt_params(interrupt_params, http_accept_header)
|
24
|
+
return redirect_response(interrupt_params) if interrupt_params['location']
|
49
25
|
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
def graphql_response(gateway_multiplex)
|
54
|
-
multiplex_return = []
|
55
|
-
gateway_multiplex.queries.each do |query|
|
56
|
-
# This method is only called in places where GraphQL-Ruby is already required
|
57
|
-
query_result = ::GraphQL::Query::Result.new(
|
58
|
-
query: query,
|
59
|
-
values: JSON.parse(content('application/json'))
|
60
|
-
)
|
61
|
-
multiplex_return << query_result
|
62
|
-
end
|
63
|
-
|
64
|
-
multiplex_return
|
26
|
+
block_response(interrupt_params, http_accept_header)
|
65
27
|
end
|
66
28
|
|
67
29
|
private
|
68
30
|
|
69
|
-
def
|
70
|
-
content_type =
|
71
|
-
|
72
|
-
|
73
|
-
|
31
|
+
def block_response(interrupt_params, http_accept_header)
|
32
|
+
content_type = case interrupt_params['type']
|
33
|
+
when nil, 'auto' then content_type(http_accept_header)
|
34
|
+
else FORMAT_TO_CONTENT_TYPE.fetch(interrupt_params['type'], DEFAULT_CONTENT_TYPE)
|
35
|
+
end
|
74
36
|
|
75
37
|
Response.new(
|
76
|
-
status: 403,
|
77
|
-
headers: {
|
78
|
-
body:
|
38
|
+
status: interrupt_params['status_code']&.to_i || 403,
|
39
|
+
headers: {'Content-Type' => content_type},
|
40
|
+
body: [content(content_type)],
|
79
41
|
)
|
80
42
|
end
|
81
43
|
|
82
|
-
def
|
83
|
-
|
84
|
-
content_type(env)
|
85
|
-
else
|
86
|
-
FORMAT_TO_CONTENT_TYPE[options['type']]
|
87
|
-
end
|
88
|
-
|
89
|
-
body = []
|
90
|
-
body << content(content_type)
|
44
|
+
def redirect_response(interrupt_params)
|
45
|
+
status_code = interrupt_params['status_code'].to_i
|
91
46
|
|
92
47
|
Response.new(
|
93
|
-
status:
|
94
|
-
headers: {
|
95
|
-
body:
|
48
|
+
status: ((status_code >= 300 && status_code < 400) ? status_code : 303),
|
49
|
+
headers: {'Location' => interrupt_params.fetch('location')},
|
50
|
+
body: [],
|
96
51
|
)
|
97
52
|
end
|
98
53
|
|
99
|
-
def redirect_response(env, options)
|
100
|
-
if options['location'] && !options['location'].empty?
|
101
|
-
content_type = content_type(env)
|
102
|
-
|
103
|
-
status = options['status_code'] >= 300 && options['status_code'] < 400 ? options['status_code'] : 303
|
104
|
-
|
105
|
-
headers = {
|
106
|
-
'Content-Type' => content_type,
|
107
|
-
'Location' => options['location']
|
108
|
-
}
|
109
|
-
|
110
|
-
Response.new(
|
111
|
-
status: status,
|
112
|
-
headers: headers,
|
113
|
-
body: [],
|
114
|
-
)
|
115
|
-
else
|
116
|
-
default_response(env)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
54
|
CONTENT_TYPE_TO_FORMAT = {
|
121
55
|
'application/json' => :json,
|
122
56
|
'text/html' => :html,
|
@@ -130,10 +64,10 @@ module Datadog
|
|
130
64
|
|
131
65
|
DEFAULT_CONTENT_TYPE = 'application/json'
|
132
66
|
|
133
|
-
def content_type(
|
134
|
-
return DEFAULT_CONTENT_TYPE
|
67
|
+
def content_type(http_accept_header)
|
68
|
+
return DEFAULT_CONTENT_TYPE if http_accept_header.nil?
|
135
69
|
|
136
|
-
accept_types =
|
70
|
+
accept_types = http_accept_header.split(',').map(&:strip)
|
137
71
|
|
138
72
|
accepted = accept_types.map { |m| Utils::HTTP::MediaRange.new(m) }.sort!.reverse!
|
139
73
|
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module AppSec
|
5
|
+
module SecurityEngine
|
6
|
+
# A namespace for value-objects representing the result of WAF check.
|
7
|
+
module Result
|
8
|
+
# A generic result without indication of its type.
|
9
|
+
class Base
|
10
|
+
attr_reader :events, :actions, :derivatives, :duration_ns, :duration_ext_ns
|
11
|
+
|
12
|
+
def initialize(events:, actions:, derivatives:, timeout:, duration_ns:, duration_ext_ns:)
|
13
|
+
@events = events
|
14
|
+
@actions = actions
|
15
|
+
@derivatives = derivatives
|
16
|
+
|
17
|
+
@timeout = timeout
|
18
|
+
@duration_ns = duration_ns
|
19
|
+
@duration_ext_ns = duration_ext_ns
|
20
|
+
end
|
21
|
+
|
22
|
+
def timeout?
|
23
|
+
!!@timeout
|
24
|
+
end
|
25
|
+
|
26
|
+
def match?
|
27
|
+
raise NotImplementedError
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# A result that indicates a security rule match
|
32
|
+
class Match < Base
|
33
|
+
def match?
|
34
|
+
true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# A result that indicates a successful security rules check without a match
|
39
|
+
class Ok < Base
|
40
|
+
def match?
|
41
|
+
false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# A result that indicates an internal security library error
|
46
|
+
class Error
|
47
|
+
attr_reader :events, :actions, :derivatives, :duration_ns, :duration_ext_ns
|
48
|
+
|
49
|
+
def initialize(duration_ext_ns:)
|
50
|
+
@events = []
|
51
|
+
@actions = @derivatives = {}
|
52
|
+
@duration_ns = 0
|
53
|
+
@duration_ext_ns = duration_ext_ns
|
54
|
+
end
|
55
|
+
|
56
|
+
def timeout?
|
57
|
+
false
|
58
|
+
end
|
59
|
+
|
60
|
+
def match?
|
61
|
+
false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'result'
|
4
|
+
|
5
|
+
module Datadog
|
6
|
+
module AppSec
|
7
|
+
module SecurityEngine
|
8
|
+
# A class that check input via security engine (WAF) and respond with result.
|
9
|
+
class Runner
|
10
|
+
SUCCESSFUL_EXECUTION_CODES = [:ok, :match].freeze
|
11
|
+
|
12
|
+
def initialize(handle, telemetry:)
|
13
|
+
@mutex = Mutex.new
|
14
|
+
@context = WAF::Context.new(handle)
|
15
|
+
@telemetry = telemetry
|
16
|
+
|
17
|
+
@debug_tag = "libddwaf:#{WAF::VERSION::STRING} method:ddwaf_run"
|
18
|
+
end
|
19
|
+
|
20
|
+
def run(persistent_data, ephemeral_data, timeout = WAF::LibDDWAF::DDWAF_RUN_TIMEOUT)
|
21
|
+
@mutex.lock
|
22
|
+
|
23
|
+
start_ns = Core::Utils::Time.get_time(:nanosecond)
|
24
|
+
persistent_data.reject! do |_, v|
|
25
|
+
next false if v.is_a?(TrueClass) || v.is_a?(FalseClass)
|
26
|
+
|
27
|
+
v.nil? || v.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
ephemeral_data.reject! do |_, v|
|
31
|
+
next false if v.is_a?(TrueClass) || v.is_a?(FalseClass)
|
32
|
+
|
33
|
+
v.nil? || v.empty?
|
34
|
+
end
|
35
|
+
|
36
|
+
_code, result = try_run(persistent_data, ephemeral_data, timeout)
|
37
|
+
stop_ns = Core::Utils::Time.get_time(:nanosecond)
|
38
|
+
|
39
|
+
report_execution(result)
|
40
|
+
|
41
|
+
unless SUCCESSFUL_EXECUTION_CODES.include?(result.status)
|
42
|
+
return Result::Error.new(duration_ext_ns: stop_ns - start_ns)
|
43
|
+
end
|
44
|
+
|
45
|
+
klass = (result.status == :match) ? Result::Match : Result::Ok
|
46
|
+
klass.new(
|
47
|
+
events: result.events,
|
48
|
+
actions: result.actions,
|
49
|
+
derivatives: result.derivatives,
|
50
|
+
timeout: result.timeout,
|
51
|
+
duration_ns: result.total_runtime,
|
52
|
+
duration_ext_ns: (stop_ns - start_ns)
|
53
|
+
)
|
54
|
+
ensure
|
55
|
+
@mutex.unlock
|
56
|
+
end
|
57
|
+
|
58
|
+
def finalize
|
59
|
+
@context.finalize
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def try_run(persistent_data, ephemeral_data, timeout)
|
65
|
+
@context.run(persistent_data, ephemeral_data, timeout)
|
66
|
+
rescue WAF::LibDDWAF::Error => e
|
67
|
+
Datadog.logger.debug { "#{@debug_tag} execution error: #{e} backtrace: #{e.backtrace&.first(3)}" }
|
68
|
+
@telemetry.report(e, description: 'libddwaf-rb internal low-level error')
|
69
|
+
|
70
|
+
[:err_internal, WAF::Result.new(:err_internal, [], 0, false, [], [])]
|
71
|
+
end
|
72
|
+
|
73
|
+
def report_execution(result)
|
74
|
+
Datadog.logger.debug { "#{@debug_tag} execution timed out: #{result.inspect}" } if result.timeout
|
75
|
+
|
76
|
+
if SUCCESSFUL_EXECUTION_CODES.include?(result.status)
|
77
|
+
Datadog.logger.debug { "#{@debug_tag} execution result: #{result.inspect}" }
|
78
|
+
else
|
79
|
+
message = "#{@debug_tag} execution error: #{result.status.inspect}"
|
80
|
+
|
81
|
+
Datadog.logger.debug { message }
|
82
|
+
@telemetry.error(message)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|