ddtrace 1.11.1 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +49 -1
  3. data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +6 -4
  4. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +34 -16
  5. data/ext/ddtrace_profiling_native_extension/extconf.rb +17 -3
  6. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +2 -2
  7. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +38 -4
  8. data/lib/datadog/appsec/assets/waf_rules/recommended.json +489 -133
  9. data/lib/datadog/appsec/assets/waf_rules/strict.json +2 -47
  10. data/lib/datadog/appsec/configuration/settings.rb +2 -10
  11. data/lib/datadog/appsec/configuration.rb +3 -9
  12. data/lib/datadog/appsec/contrib/rack/ext.rb +0 -1
  13. data/lib/datadog/appsec/contrib/rack/gateway/request.rb +12 -0
  14. data/lib/datadog/appsec/contrib/rack/gateway/response.rb +3 -3
  15. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +9 -9
  16. data/lib/datadog/appsec/contrib/rack/integration.rb +0 -5
  17. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +7 -1
  18. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +1 -1
  19. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +33 -25
  20. data/lib/datadog/appsec/contrib/rails/ext.rb +0 -1
  21. data/lib/datadog/appsec/contrib/rails/framework.rb +1 -13
  22. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +3 -3
  23. data/lib/datadog/appsec/contrib/rails/integration.rb +0 -5
  24. data/lib/datadog/appsec/contrib/rails/patcher.rb +1 -1
  25. data/lib/datadog/appsec/contrib/sinatra/ext.rb +0 -1
  26. data/lib/datadog/appsec/contrib/sinatra/framework.rb +1 -13
  27. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +6 -6
  28. data/lib/datadog/appsec/contrib/sinatra/integration.rb +0 -5
  29. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +5 -4
  30. data/lib/datadog/appsec/event.rb +5 -5
  31. data/lib/datadog/appsec/ext.rb +1 -0
  32. data/lib/datadog/appsec/extensions.rb +2 -6
  33. data/lib/datadog/appsec/monitor/gateway/watcher.rb +3 -4
  34. data/lib/datadog/appsec/processor/rule_merger.rb +13 -7
  35. data/lib/datadog/appsec/processor.rb +0 -45
  36. data/lib/datadog/appsec/remote.rb +6 -0
  37. data/lib/datadog/appsec/scope.rb +61 -0
  38. data/lib/datadog/appsec.rb +6 -0
  39. data/lib/datadog/ci/ext/environment.rb +40 -4
  40. data/lib/datadog/core/configuration/settings.rb +66 -14
  41. data/lib/datadog/core/configuration.rb +5 -1
  42. data/lib/datadog/core/remote/client/capabilities.rb +1 -1
  43. data/lib/datadog/core/telemetry/collector.rb +2 -1
  44. data/lib/datadog/core/telemetry/v1/dependency.rb +2 -1
  45. data/lib/datadog/kit/appsec/events.rb +58 -13
  46. data/lib/datadog/kit/identity.rb +29 -10
  47. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +2 -0
  48. data/lib/datadog/profiling/component.rb +54 -29
  49. data/lib/datadog/tracing/buffer.rb +0 -1
  50. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +9 -1
  51. data/lib/datadog/tracing/contrib/aws/ext.rb +11 -1
  52. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +7 -0
  53. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +4 -0
  54. data/lib/datadog/tracing/contrib/aws/service/base.rb +16 -0
  55. data/lib/datadog/tracing/contrib/aws/service/dynamodb.rb +19 -0
  56. data/lib/datadog/tracing/contrib/aws/service/eventbridge.rb +19 -0
  57. data/lib/datadog/tracing/contrib/aws/service/kinesis.rb +29 -0
  58. data/lib/datadog/tracing/contrib/aws/service/s3.rb +19 -0
  59. data/lib/datadog/tracing/contrib/aws/service/sns.rb +27 -0
  60. data/lib/datadog/tracing/contrib/aws/service/sqs.rb +24 -0
  61. data/lib/datadog/tracing/contrib/aws/service/stepfunctions.rb +37 -0
  62. data/lib/datadog/tracing/contrib/aws/services.rb +10 -0
  63. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +6 -1
  64. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +5 -2
  65. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +6 -1
  66. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +4 -2
  67. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +6 -1
  68. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +5 -2
  69. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +6 -1
  70. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +5 -2
  71. data/lib/datadog/tracing/contrib/patcher.rb +0 -1
  72. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +6 -1
  73. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +5 -2
  74. data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +6 -1
  75. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +4 -2
  76. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +10 -2
  77. data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +9 -1
  78. data/lib/datadog/tracing/contrib/racecar/event.rb +3 -1
  79. data/lib/datadog/tracing/contrib/rack/middlewares.rb +3 -1
  80. data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +6 -1
  81. data/lib/datadog/tracing/contrib/redis/tags.rb +4 -1
  82. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +6 -1
  83. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +4 -1
  84. data/lib/datadog/tracing/contrib/roda/patcher.rb +1 -1
  85. data/lib/datadog/tracing/contrib/sequel/database.rb +4 -1
  86. data/lib/datadog/tracing/contrib/sequel/dataset.rb +4 -1
  87. data/lib/datadog/tracing/contrib/sequel/utils.rb +4 -1
  88. data/lib/datadog/tracing/contrib/status_code_matcher.rb +0 -1
  89. data/lib/datadog/tracing/correlation.rb +0 -1
  90. data/lib/datadog/tracing/distributed/headers/ext.rb +1 -1
  91. data/lib/datadog/tracing/event.rb +0 -2
  92. data/lib/datadog/tracing/pipeline.rb +0 -2
  93. data/lib/datadog/tracing/runtime/metrics.rb +0 -2
  94. data/lib/datadog/tracing/sampling/rate_by_service_sampler.rb +0 -1
  95. data/lib/datadog/tracing/sampling/rate_sampler.rb +0 -2
  96. data/lib/datadog/tracing/sampling/rule.rb +0 -2
  97. data/lib/datadog/tracing/sampling/rule_sampler.rb +0 -2
  98. data/lib/datadog/tracing/span_operation.rb +0 -1
  99. data/lib/datadog/tracing/sync_writer.rb +0 -2
  100. data/lib/datadog/tracing/trace_operation.rb +0 -1
  101. data/lib/datadog/tracing/tracer.rb +0 -1
  102. data/lib/datadog/tracing/workers/trace_writer.rb +0 -1
  103. data/lib/datadog/tracing/workers.rb +0 -2
  104. data/lib/datadog/tracing/writer.rb +0 -2
  105. data/lib/ddtrace/version.rb +2 -2
  106. metadata +18 -19
  107. data/lib/datadog/appsec/contrib/configuration/settings.rb +0 -20
  108. data/lib/datadog/appsec/contrib/rack/configuration/settings.rb +0 -22
  109. data/lib/datadog/appsec/contrib/rails/configuration/settings.rb +0 -22
  110. data/lib/datadog/appsec/contrib/sinatra/configuration/settings.rb +0 -22
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": "2.2",
3
3
  "metadata": {
4
- "rules_version": "1.5.2"
4
+ "rules_version": "1.7.0"
5
5
  },
6
6
  "rules": [
7
7
  {
@@ -24,96 +24,51 @@
24
24
  }
25
25
  ],
26
26
  "list": [
27
- "",
28
27
  "(hydra)",
29
- ".nasl",
30
28
  "absinthe",
31
- "advanced email extractor",
32
- "arachni/",
33
29
  "autogetcontent",
34
30
  "bilbo",
35
31
  "bfac",
36
- "brutus",
37
- "brutus/aet",
38
- "bsqlbf",
39
- "cgichk",
40
32
  "cisco-torch",
41
- "commix",
42
33
  "core-project/1.0",
43
34
  "crimscanner/",
44
35
  "datacha0s",
45
- "detectify",
46
- "dirbuster",
47
36
  "domino hunter",
48
37
  "dotdotpwn",
49
38
  "email extractor",
50
39
  "fhscan core 1.",
51
40
  "floodgate",
52
- "fuzz faster u fool",
53
41
  "f-secure radar",
54
42
  "get-minimal",
55
- "gobuster",
56
43
  "gootkit auto-rooter scanner",
57
44
  "grabber",
58
45
  "grendel-scan",
59
- "havij",
60
46
  "inspath",
61
47
  "internet ninja",
62
- "jaascois",
63
- "jorgee",
64
48
  "masscan",
65
- "metis",
66
49
  "morfeus fucking scanner",
67
50
  "mysqloit",
68
- "n-stealth",
69
- "nessus",
70
- "netsparker",
71
- "nikto",
72
- "nmap nse",
73
- "nmap scripting engine",
74
- "nmap-nse",
75
- "nsauditor",
76
- "nuclei",
77
- "openvas",
78
- "pangolin",
79
- "paros",
80
- "pmafind",
81
51
  "prog.customcrawler",
82
52
  "qqgamehall",
83
- "qualys was",
84
53
  "s.t.a.l.k.e.r.",
85
- "security scan",
86
54
  "springenwerk",
87
55
  "sql power injector",
88
- "sqlmap",
89
- "sqlninja",
90
56
  "struts-pwn",
91
57
  "sysscan",
92
58
  "tbi-webscanner",
93
59
  "teh forest lobster",
94
- "this is an exploit",
95
60
  "toata dragostea",
96
- "toata dragostea mea pentru diavola",
97
61
  "uil2pn",
98
62
  "user-agent:",
99
63
  "vega/",
100
64
  "voideye",
101
- "w3af.sf.net",
102
- "w3af.sourceforge.net",
103
- "w3af.org",
104
65
  "webbandit",
105
- "webinspect",
106
66
  "webshag",
107
- "webtrends security analyzer",
108
67
  "webvulnscan",
109
- "wfuzz",
110
68
  "whatweb",
111
69
  "whcc/",
112
70
  "wordpress hash grabber",
113
- "wpscan",
114
- "xmlrpc exploit",
115
- "zgrab",
116
- "zmeu"
71
+ "xmlrpc exploit"
117
72
  ]
118
73
  },
119
74
  "operator": "phrase_match"
@@ -116,7 +116,7 @@ module Datadog
116
116
  }.freeze
117
117
 
118
118
  # Struct constant whisker cast for Steep
119
- Integration = _ = Struct.new(:integration, :options) # rubocop:disable Naming/ConstantName
119
+ Integration = _ = Struct.new(:integration) # rubocop:disable Naming/ConstantName
120
120
 
121
121
  def initialize
122
122
  @integrations = []
@@ -181,14 +181,6 @@ module Datadog
181
181
  _ = @options[:obfuscator_value_regex]
182
182
  end
183
183
 
184
- def [](integration_name)
185
- integration = Datadog::AppSec::Contrib::Integration.registry[integration_name]
186
-
187
- raise ArgumentError, "'#{integration_name}' is not a valid integration." unless integration
188
-
189
- integration.options
190
- end
191
-
192
184
  def merge(dsl)
193
185
  dsl.options.each do |k, v|
194
186
  unless v.nil?
@@ -203,7 +195,7 @@ module Datadog
203
195
  dsl.instruments.each do |instrument|
204
196
  # TODO: error handling
205
197
  registered_integration = Datadog::AppSec::Contrib::Integration.registry[instrument.name]
206
- @integrations << Integration.new(registered_integration, instrument.options)
198
+ @integrations << Integration.new(registered_integration)
207
199
 
208
200
  # TODO: move to a separate apply step
209
201
  klass = registered_integration.klass
@@ -15,7 +15,7 @@ module Datadog
15
15
  # Configuration DSL implementation
16
16
  class DSL
17
17
  # Struct constant whisker cast for Steep
18
- Instrument = _ = Struct.new(:name, :options) # rubocop:disable Naming/ConstantName
18
+ Instrument = _ = Struct.new(:name) # rubocop:disable Naming/ConstantName
19
19
 
20
20
  def initialize
21
21
  @instruments = []
@@ -24,8 +24,8 @@ module Datadog
24
24
 
25
25
  attr_reader :instruments, :options
26
26
 
27
- def instrument(name, options = {})
28
- @instruments << Instrument.new(name, options)
27
+ def instrument(name)
28
+ @instruments << Instrument.new(name)
29
29
  end
30
30
 
31
31
  def enabled=(value)
@@ -64,12 +64,6 @@ module Datadog
64
64
  def obfuscator_value_regex=(value)
65
65
  options[:obfuscator_value_regex] = value
66
66
  end
67
-
68
- def [](key)
69
- found = @instruments.find { |e| e.name == key }
70
-
71
- found.options if found
72
- end
73
67
  end
74
68
 
75
69
  # class-level methods for Configuration
@@ -5,7 +5,6 @@ module Datadog
5
5
  # Rack integration constants
6
6
  module Ext
7
7
  APP = 'rack'.freeze
8
- ENV_ENABLED = 'DD_TRACE_RACK_ENABLED'.freeze # TODO: DD_APPSEC?
9
8
  end
10
9
  end
11
10
  end
@@ -33,6 +33,10 @@ module Datadog
33
33
  end
34
34
  end
35
35
 
36
+ def method
37
+ request.request_method
38
+ end
39
+
36
40
  def headers
37
41
  request.env.each_with_object({}) do |(k, v), h|
38
42
  h[k.gsub(/^HTTP_/, '').downcase.tr('_', '-')] = v if k =~ /^HTTP_/
@@ -47,6 +51,14 @@ module Datadog
47
51
  request.url
48
52
  end
49
53
 
54
+ def fullpath
55
+ request.fullpath
56
+ end
57
+
58
+ def path
59
+ request.path
60
+ end
61
+
50
62
  def cookies
51
63
  request.cookies
52
64
  end
@@ -9,14 +9,14 @@ module Datadog
9
9
  module Gateway
10
10
  # Gateway Response argument.
11
11
  class Response < Instrumentation::Gateway::Argument
12
- attr_reader :body, :status, :headers, :active_context
12
+ attr_reader :body, :status, :headers, :scope
13
13
 
14
- def initialize(body, status, headers, active_context:)
14
+ def initialize(body, status, headers, scope:)
15
15
  super()
16
16
  @body = body
17
17
  @status = status
18
18
  @headers = headers.each_with_object({}) { |(k, v), h| h[k.downcase] = v }
19
- @active_context = active_context
19
+ @scope = scope
20
20
  end
21
21
 
22
22
  def response
@@ -25,13 +25,13 @@ module Datadog
25
25
  gateway.watch('rack.request', :appsec) do |stack, gateway_request|
26
26
  block = false
27
27
  event = nil
28
- waf_context = gateway_request.env['datadog.waf.context']
28
+ scope = gateway_request.env[Datadog::AppSec::Ext::SCOPE_KEY]
29
29
 
30
30
  AppSec::Reactive::Operation.new('rack.request') do |op|
31
31
  trace = active_trace
32
32
  span = active_span
33
33
 
34
- Rack::Reactive::Request.subscribe(op, waf_context) do |result, _block|
34
+ Rack::Reactive::Request.subscribe(op, scope.processor_context) do |result, _block|
35
35
  if result.status == :match
36
36
  # TODO: should this hash be an Event instance instead?
37
37
  event = {
@@ -44,7 +44,7 @@ module Datadog
44
44
 
45
45
  span.set_tag('appsec.event', 'true') if span
46
46
 
47
- waf_context.events << event
47
+ scope.processor_context.events << event
48
48
  end
49
49
  end
50
50
 
@@ -68,13 +68,13 @@ module Datadog
68
68
  gateway.watch('rack.response', :appsec) do |stack, gateway_response|
69
69
  block = false
70
70
  event = nil
71
- waf_context = gateway_response.active_context
71
+ scope = gateway_response.scope
72
72
 
73
73
  AppSec::Reactive::Operation.new('rack.response') do |op|
74
74
  trace = active_trace
75
75
  span = active_span
76
76
 
77
- Rack::Reactive::Response.subscribe(op, waf_context) do |result, _block|
77
+ Rack::Reactive::Response.subscribe(op, scope.processor_context) do |result, _block|
78
78
  if result.status == :match
79
79
  # TODO: should this hash be an Event instance instead?
80
80
  event = {
@@ -87,7 +87,7 @@ module Datadog
87
87
 
88
88
  span.set_tag('appsec.event', 'true') if span
89
89
 
90
- waf_context.events << event
90
+ scope.processor_context.events << event
91
91
  end
92
92
  end
93
93
 
@@ -111,13 +111,13 @@ module Datadog
111
111
  gateway.watch('rack.request.body', :appsec) do |stack, gateway_request|
112
112
  block = false
113
113
  event = nil
114
- waf_context = gateway_request.env['datadog.waf.context']
114
+ scope = gateway_request.env[Datadog::AppSec::Ext::SCOPE_KEY]
115
115
 
116
116
  AppSec::Reactive::Operation.new('rack.request.body') do |op|
117
117
  trace = active_trace
118
118
  span = active_span
119
119
 
120
- Rack::Reactive::RequestBody.subscribe(op, waf_context) do |result, _block|
120
+ Rack::Reactive::RequestBody.subscribe(op, scope.processor_context) do |result, _block|
121
121
  if result.status == :match
122
122
  # TODO: should this hash be an Event instance instead?
123
123
  event = {
@@ -130,7 +130,7 @@ module Datadog
130
130
 
131
131
  span.set_tag('appsec.event', 'true') if span
132
132
 
133
- waf_context.events << event
133
+ scope.processor_context.events << event
134
134
  end
135
135
  end
136
136
 
@@ -1,6 +1,5 @@
1
1
  require_relative '../integration'
2
2
 
3
- require_relative 'configuration/settings'
4
3
  require_relative 'patcher'
5
4
  require_relative 'request_middleware'
6
5
  require_relative 'request_body_middleware'
@@ -33,10 +32,6 @@ module Datadog
33
32
  false
34
33
  end
35
34
 
36
- def default_configuration
37
- Configuration::Settings.new
38
- end
39
-
40
35
  def patcher
41
36
  Patcher
42
37
  end
@@ -13,6 +13,7 @@ module Datadog
13
13
  'request.query',
14
14
  'request.cookies',
15
15
  'request.client_ip',
16
+ 'server.request.method'
16
17
  ].freeze
17
18
  private_constant :ADDRESSES
18
19
 
@@ -20,14 +21,16 @@ module Datadog
20
21
  catch(:block) do
21
22
  op.publish('request.query', gateway_request.query)
22
23
  op.publish('request.headers', gateway_request.headers)
23
- op.publish('request.uri.raw', gateway_request.url)
24
+ op.publish('request.uri.raw', gateway_request.fullpath)
24
25
  op.publish('request.cookies', gateway_request.cookies)
25
26
  op.publish('request.client_ip', gateway_request.client_ip)
27
+ op.publish('server.request.method', gateway_request.method)
26
28
 
27
29
  nil
28
30
  end
29
31
  end
30
32
 
33
+ # rubocop:disable Metrics/MethodLength
31
34
  def self.subscribe(op, waf_context)
32
35
  op.subscribe(*ADDRESSES) do |*values|
33
36
  Datadog.logger.debug { "reacted to #{ADDRESSES.inspect}: #{values.inspect}" }
@@ -37,6 +40,7 @@ module Datadog
37
40
  query = values[2]
38
41
  cookies = values[3]
39
42
  client_ip = values[4]
43
+ request_method = values[5]
40
44
 
41
45
  waf_args = {
42
46
  'server.request.cookies' => cookies,
@@ -45,6 +49,7 @@ module Datadog
45
49
  'server.request.headers' => headers,
46
50
  'server.request.headers.no_cookies' => headers_no_cookies,
47
51
  'http.client_ip' => client_ip,
52
+ 'server.request.method' => request_method,
48
53
  }
49
54
 
50
55
  waf_timeout = Datadog::AppSec.settings.waf_timeout
@@ -71,6 +76,7 @@ module Datadog
71
76
  Datadog.logger.debug { "WAF UNKNOWN: #{result.status.inspect} #{result.inspect}" }
72
77
  end
73
78
  end
79
+ # rubocop:enable Metrics/MethodLength
74
80
  end
75
81
  end
76
82
  end
@@ -17,7 +17,7 @@ module Datadog
17
17
  end
18
18
 
19
19
  def call(env)
20
- context = env['datadog.waf.context']
20
+ context = env[Datadog::AppSec::Ext::SCOPE_KEY]
21
21
 
22
22
  return @app.call(env) unless context
23
23
 
@@ -2,7 +2,6 @@ require 'json'
2
2
 
3
3
  require_relative 'gateway/request'
4
4
  require_relative 'gateway/response'
5
- require_relative '../../ext'
6
5
  require_relative '../../instrumentation/gateway'
7
6
  require_relative '../../processor'
8
7
  require_relative '../../response'
@@ -23,7 +22,7 @@ module Datadog
23
22
  @oneshot_tags_sent = false
24
23
  end
25
24
 
26
- # rubocop:disable Metrics/PerceivedComplexity,Metrics/CyclomaticComplexity,Metrics/MethodLength
25
+ # rubocop:disable Metrics/AbcSize,Metrics/PerceivedComplexity,Metrics/CyclomaticComplexity,Metrics/MethodLength
27
26
  def call(env)
28
27
  return @app.call(env) unless Datadog::AppSec.enabled?
29
28
 
@@ -31,14 +30,19 @@ module Datadog
31
30
 
32
31
  processor = nil
33
32
  ready = false
34
- context = nil
33
+ scope = nil
34
+
35
+ # For a given request, keep using the first Rack stack scope for
36
+ # nested apps. Don't set `context` local variable so that on popping
37
+ # out of this nested stack we don't finalize the parent's context
38
+ return @app.call(env) if active_scope(env)
35
39
 
36
40
  Datadog::AppSec.reconfigure_lock do
37
41
  processor = Datadog::AppSec.processor
38
42
 
39
43
  if !processor.nil? && processor.ready?
40
- context = processor.activate_context
41
- env['datadog.waf.context'] = context
44
+ scope = Datadog::AppSec::Scope.activate_scope(active_trace, active_span, processor)
45
+ env[Datadog::AppSec::Ext::SCOPE_KEY] = scope
42
46
  ready = true
43
47
  end
44
48
  end
@@ -65,17 +69,17 @@ module Datadog
65
69
  request_return[2],
66
70
  request_return[0],
67
71
  request_return[1],
68
- active_context: context
72
+ scope: scope
69
73
  )
70
74
 
71
75
  _response_return, response_response = Instrumentation.gateway.push('rack.response', gateway_response)
72
76
 
73
- context.events.each do |e|
77
+ scope.processor_context.events.each do |e|
74
78
  e[:response] ||= gateway_response
75
79
  e[:request] ||= gateway_request
76
80
  end
77
81
 
78
- AppSec::Event.record(*context.events)
82
+ AppSec::Event.record(active_span, *scope.processor_context.events)
79
83
 
80
84
  if response_response && response_response.any? { |action, _event| action == :block }
81
85
  request_return = AppSec::Response.negotiate(env).to_rack
@@ -83,15 +87,19 @@ module Datadog
83
87
 
84
88
  request_return
85
89
  ensure
86
- if context
87
- add_waf_runtime_tags(active_trace, context)
88
- processor.deactivate_context
90
+ if scope
91
+ add_waf_runtime_tags(active_span, scope.processor_context)
92
+ Datadog::AppSec::Scope.deactivate_scope
89
93
  end
90
94
  end
91
- # rubocop:enable Metrics/PerceivedComplexity,Metrics/CyclomaticComplexity,Metrics/MethodLength
95
+ # rubocop:enable Metrics/AbcSize,Metrics/PerceivedComplexity,Metrics/CyclomaticComplexity,Metrics/MethodLength
92
96
 
93
97
  private
94
98
 
99
+ def active_scope(env)
100
+ env[Datadog::AppSec::Ext::SCOPE_KEY]
101
+ end
102
+
95
103
  def active_trace
96
104
  # TODO: factor out tracing availability detection
97
105
 
@@ -111,9 +119,9 @@ module Datadog
111
119
  def add_appsec_tags(processor, trace, span, env)
112
120
  return unless trace
113
121
 
114
- trace.set_tag('_dd.appsec.enabled', 1)
115
- trace.set_tag('_dd.runtime_family', 'ruby')
116
- trace.set_tag('_dd.appsec.waf.version', Datadog::AppSec::WAF::VERSION::BASE_STRING)
122
+ span.set_tag('_dd.appsec.enabled', 1)
123
+ span.set_tag('_dd.runtime_family', 'ruby')
124
+ span.set_tag('_dd.appsec.waf.version', Datadog::AppSec::WAF::VERSION::BASE_STRING)
117
125
 
118
126
  if span && span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_CLIENT_IP).nil?
119
127
  request_header_collection = Datadog::Tracing::Contrib::Rack::Header::RequestHeaderCollection.new(env)
@@ -127,17 +135,17 @@ module Datadog
127
135
  end
128
136
 
129
137
  if processor.ruleset_info
130
- trace.set_tag('_dd.appsec.event_rules.version', processor.ruleset_info[:version])
138
+ span.set_tag('_dd.appsec.event_rules.version', processor.ruleset_info[:version])
131
139
 
132
140
  unless @oneshot_tags_sent
133
141
  # Small race condition, but it's inoccuous: worst case the tags
134
142
  # are sent a couple of times more than expected
135
143
  @oneshot_tags_sent = true
136
144
 
137
- trace.set_tag('_dd.appsec.event_rules.loaded', processor.ruleset_info[:loaded].to_f)
138
- trace.set_tag('_dd.appsec.event_rules.error_count', processor.ruleset_info[:failed].to_f)
139
- trace.set_tag('_dd.appsec.event_rules.errors', JSON.dump(processor.ruleset_info[:errors]))
140
- trace.set_tag('_dd.appsec.event_rules.addresses', JSON.dump(processor.addresses))
145
+ span.set_tag('_dd.appsec.event_rules.loaded', processor.ruleset_info[:loaded].to_f)
146
+ span.set_tag('_dd.appsec.event_rules.error_count', processor.ruleset_info[:failed].to_f)
147
+ span.set_tag('_dd.appsec.event_rules.errors', JSON.dump(processor.ruleset_info[:errors]))
148
+ span.set_tag('_dd.appsec.event_rules.addresses', JSON.dump(processor.addresses))
141
149
 
142
150
  # Ensure these tags reach the backend
143
151
  trace.keep!
@@ -149,15 +157,15 @@ module Datadog
149
157
  end
150
158
  end
151
159
 
152
- def add_waf_runtime_tags(trace, context)
153
- return unless trace
160
+ def add_waf_runtime_tags(span, context)
161
+ return unless span
154
162
  return unless context
155
163
 
156
- trace.set_tag('_dd.appsec.waf.timeouts', context.timeouts)
164
+ span.set_tag('_dd.appsec.waf.timeouts', context.timeouts)
157
165
 
158
166
  # these tags expect time in us
159
- trace.set_tag('_dd.appsec.waf.duration', context.time_ns / 1000.0)
160
- trace.set_tag('_dd.appsec.waf.duration_ext', context.time_ext_ns / 1000.0)
167
+ span.set_tag('_dd.appsec.waf.duration', context.time_ns / 1000.0)
168
+ span.set_tag('_dd.appsec.waf.duration_ext', context.time_ext_ns / 1000.0)
161
169
  end
162
170
  end
163
171
  end
@@ -5,7 +5,6 @@ module Datadog
5
5
  # Rack integration constants
6
6
  module Ext
7
7
  APP = 'rails'.freeze
8
- ENV_ENABLED = 'DD_TRACE_RAILS_ENABLED'.freeze
9
8
  end
10
9
  end
11
10
  end
@@ -8,21 +8,9 @@ module Datadog
8
8
  module Framework
9
9
  def self.setup
10
10
  Datadog::AppSec.configure do |datadog_config|
11
- rails_config = config_with_defaults(datadog_config)
12
- activate_rack!(datadog_config, rails_config)
11
+ datadog_config.instrument(:rack)
13
12
  end
14
13
  end
15
-
16
- def self.config_with_defaults(datadog_config)
17
- datadog_config[:rails]
18
- end
19
-
20
- # Apply relevant configuration from Sinatra to Rack
21
- def self.activate_rack!(datadog_config, sinatra_config)
22
- datadog_config.instrument(
23
- :rack,
24
- )
25
- end
26
14
  end
27
15
  end
28
16
  end
@@ -21,13 +21,13 @@ module Datadog
21
21
  gateway.watch('rails.request.action', :appsec) do |stack, gateway_request|
22
22
  block = false
23
23
  event = nil
24
- waf_context = gateway_request.env['datadog.waf.context']
24
+ scope = gateway_request.env[Datadog::AppSec::Ext::SCOPE_KEY]
25
25
 
26
26
  AppSec::Reactive::Operation.new('rails.request.action') do |op|
27
27
  trace = active_trace
28
28
  span = active_span
29
29
 
30
- Rails::Reactive::Action.subscribe(op, waf_context) do |result, _block|
30
+ Rails::Reactive::Action.subscribe(op, scope.processor_context) do |result, _block|
31
31
  if result.status == :match
32
32
  # TODO: should this hash be an Event instance instead?
33
33
  event = {
@@ -40,7 +40,7 @@ module Datadog
40
40
 
41
41
  span.set_tag('appsec.event', 'true') if span
42
42
 
43
- waf_context.events << event
43
+ scope.processor_context.events << event
44
44
  end
45
45
  end
46
46
 
@@ -1,6 +1,5 @@
1
1
  require_relative '../integration'
2
2
 
3
- require_relative 'configuration/settings'
4
3
  require_relative 'patcher'
5
4
  require_relative 'request_middleware'
6
5
 
@@ -32,10 +31,6 @@ module Datadog
32
31
  true
33
32
  end
34
33
 
35
- def default_configuration
36
- Configuration::Settings.new
37
- end
38
-
39
34
  def patcher
40
35
  Patcher
41
36
  end
@@ -72,7 +72,7 @@ module Datadog
72
72
  def process_action(*args)
73
73
  env = request.env
74
74
 
75
- context = env['datadog.waf.context']
75
+ context = env[Datadog::AppSec::Ext::SCOPE_KEY]
76
76
 
77
77
  return super unless context
78
78
 
@@ -5,7 +5,6 @@ module Datadog
5
5
  # Sinatra integration constants
6
6
  module Ext
7
7
  APP = 'sinatra'.freeze
8
- ENV_ENABLED = 'DD_TRACE_SINATRA_ENABLED'.freeze
9
8
  ROUTE_INTERRUPT = :datadog_appsec_contrib_sinatra_route_interrupt
10
9
  end
11
10
  end
@@ -12,21 +12,9 @@ module Datadog
12
12
  # Configure Rack from Sinatra, but only if Rack has not been configured manually beforehand
13
13
  def self.setup
14
14
  Datadog::AppSec.configure do |datadog_config|
15
- sinatra_config = config_with_defaults(datadog_config)
16
- activate_rack!(datadog_config, sinatra_config)
15
+ datadog_config.instrument(:rack)
17
16
  end
18
17
  end
19
-
20
- def self.config_with_defaults(datadog_config)
21
- datadog_config[:sinatra]
22
- end
23
-
24
- # Apply relevant configuration from Sinatra to Rack
25
- def self.activate_rack!(datadog_config, sinatra_config)
26
- datadog_config.instrument(
27
- :rack,
28
- )
29
- end
30
18
  end
31
19
  end
32
20
  end