aikido-zen 1.0.1.beta.3-x86_64-mingw-64 → 1.0.1.beta.5-x86_64-mingw-64

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b137ca8d4f6f67972cf4ebcd10b10d1873e8ab98fae4435d94c7b97ebf065f3a
4
- data.tar.gz: 815c22f6be50189e3d59a70e75cc82c379849ef07928fa497b4b37b98a3bf095
3
+ metadata.gz: c35cec4c784296981a3deb9fe1fd2d34fd6a653fbd6d2d3037c24632bfe0322e
4
+ data.tar.gz: a6f19f666167e9c39b5c273bea3481b2acf2e2dd817bee5aee9bb9b3da3a0252
5
5
  SHA512:
6
- metadata.gz: 0e21978ed548096449c9b8a117f637d980f33c0b54e9d77ad3eb9bb55800bd8412d2e3cd88e4e5742d1961383ddf560d3f8fe89f0c661b2a7751646dc93ac98e
7
- data.tar.gz: 6b6648a66fc85c6960b95d07a1146e64046e97644b0a040d54337bcc66c0daaec6ea5bbd67a83dae8510d667220ffef6c573266e637e40ad93cbb21de0651d06
6
+ metadata.gz: 9becfc0eb3e60ac46f8af101d3d6b30bcf3aa8505a8a296378ee1d0dfe278c34b578ec5e5682c59d196b2e72415adfc1d8de218511400aa971d1386bece19817
7
+ data.tar.gz: 605f53dbf38a95839ccd3effd9a9bc75900bb2b12b0b45553db16182aae66739a4d9bf7114baa34b6ec9c8ff16a05edc318529db9f8ed23aa712e51c0b09879b
@@ -10,8 +10,6 @@ module Aikido::Zen
10
10
  end
11
11
 
12
12
  initializer "aikido.add_middleware" do |app|
13
- next unless config.zen.protect?
14
-
15
13
  app.middleware.use Aikido::Zen::Middleware::SetContext
16
14
  app.middleware.use Aikido::Zen::Middleware::CheckAllowedAddresses
17
15
  # Request Tracker stats do not consider failed request or 40x, so the middleware
@@ -51,20 +49,8 @@ module Aikido::Zen
51
49
  end
52
50
 
53
51
  config.after_initialize do
54
- next unless config.zen.protect?
55
-
56
- # Make sure this is run at the end of the initialization process, so
57
- # that any gems required after aikido-zen are detected and patched
58
- # accordingly.
59
- Aikido::Zen.load_sinks!
60
-
61
- # It's important we start after loading sinks, so we can report the installed packages
52
+ # Start the Aikido Agent only once the application starts.
62
53
  Aikido::Zen.start!
63
-
64
- # Agent's bootstrap process has finished —Controllers are patched to block
65
- # unwanted requests, sinks are loaded, scanners are running—, so we mark
66
- # the agent as installed.
67
- Aikido::Zen.middleware_installed!
68
54
  end
69
55
  end
70
56
  end
@@ -7,14 +7,6 @@ module Aikido::Zen
7
7
  module Sinks
8
8
  module Async
9
9
  module HTTP
10
- def self.load_sinks!
11
- if Aikido::Zen.satisfy "async-http", ">= 0.70.0"
12
- require "async/http"
13
-
14
- ::Async::HTTP::Client.prepend(Async::HTTP::ClientExtensions)
15
- end
16
- end
17
-
18
10
  SINK = Sinks.add("async-http", scanners: [
19
11
  Scanners::SSRFScanner,
20
12
  OutboundConnectionMonitor
@@ -30,48 +22,54 @@ module Aikido::Zen
30
22
  end
31
23
  end
32
24
 
33
- module ClientExtensions
34
- extend Sinks::DSL
25
+ def self.load_sinks!
26
+ if Aikido::Zen.satisfy "async-http", ">= 0.70.0"
27
+ require "async/http"
35
28
 
36
- sink_around :call do |super_call, request|
37
- uri = URI(format("%<scheme>s://%<authority>s%<path>s", {
38
- scheme: request.scheme || scheme,
39
- authority: request.authority || authority,
40
- path: request.path
41
- }))
29
+ ::Async::HTTP::Client.class_eval do
30
+ extend Sinks::DSL
42
31
 
43
- wrapped_request = Scanners::SSRFScanner::Request.new(
44
- verb: request.method,
45
- uri: uri,
46
- headers: request.headers.to_h,
47
- header_normalizer: ->(value) { Array(value).join(", ") }
48
- )
32
+ sink_around :call do |original_call, request|
33
+ uri = URI(format("%<scheme>s://%<authority>s%<path>s", {
34
+ scheme: request.scheme || scheme,
35
+ authority: request.authority || authority,
36
+ path: request.path
37
+ }))
49
38
 
50
- # Store the request information so the DNS sinks can pick it up.
51
- context = Aikido::Zen.current_context
52
- if context
53
- prev_request = context["ssrf.request"]
54
- context["ssrf.request"] = wrapped_request
55
- end
39
+ wrapped_request = Scanners::SSRFScanner::Request.new(
40
+ verb: request.method,
41
+ uri: uri,
42
+ headers: request.headers.to_h,
43
+ header_normalizer: ->(value) { Array(value).join(", ") }
44
+ )
56
45
 
57
- connection = OutboundConnection.from_uri(uri)
46
+ # Store the request information so the DNS sinks can pick it up.
47
+ context = Aikido::Zen.current_context
48
+ if context
49
+ prev_request = context["ssrf.request"]
50
+ context["ssrf.request"] = wrapped_request
51
+ end
58
52
 
59
- Helpers.scan(wrapped_request, connection, "request")
53
+ connection = OutboundConnection.from_uri(uri)
60
54
 
61
- response = super_call.call
55
+ Helpers.scan(wrapped_request, connection, "request")
62
56
 
63
- Scanners::SSRFScanner.track_redirects(
64
- request: wrapped_request,
65
- response: Scanners::SSRFScanner::Response.new(
66
- status: response.status,
67
- headers: response.headers.to_h,
68
- header_normalizer: ->(value) { Array(value).join(", ") }
69
- )
70
- )
57
+ response = original_call.call
58
+
59
+ Scanners::SSRFScanner.track_redirects(
60
+ request: wrapped_request,
61
+ response: Scanners::SSRFScanner::Response.new(
62
+ status: response.status,
63
+ headers: response.headers.to_h,
64
+ header_normalizer: ->(value) { Array(value).join(", ") }
65
+ )
66
+ )
71
67
 
72
- response
73
- ensure
74
- context["ssrf.request"] = prev_request if context
68
+ response
69
+ ensure
70
+ context["ssrf.request"] = prev_request if context
71
+ end
72
+ end
75
73
  end
76
74
  end
77
75
  end
@@ -6,14 +6,6 @@ require_relative "../outbound_connection_monitor"
6
6
  module Aikido::Zen
7
7
  module Sinks
8
8
  module Curl
9
- def self.load_sinks!
10
- if Aikido::Zen.satisfy "curb", ">= 0.2.3"
11
- require "curb"
12
-
13
- ::Curl::Easy.prepend(Curl::EasyExtensions)
14
- end
15
- end
16
-
17
9
  SINK = Sinks.add("curb", scanners: [
18
10
  Scanners::SSRFScanner,
19
11
  OutboundConnectionMonitor
@@ -53,59 +45,65 @@ module Aikido::Zen
53
45
  end
54
46
  end
55
47
 
56
- module EasyExtensions
57
- extend Sinks::DSL
58
-
59
- sink_around :perform do |super_call|
60
- wrapped_request = Helpers.wrap_request(self)
61
-
62
- # Store the request information so the DNS sinks can pick it up.
63
- context = Aikido::Zen.current_context
64
- if context
65
- prev_request = context["ssrf.request"]
66
- context["ssrf.request"] = wrapped_request
67
- end
68
-
69
- connection = OutboundConnection.from_uri(URI(url))
70
-
71
- Helpers.scan(wrapped_request, connection, "request")
72
-
73
- response = super_call.call
74
-
75
- Scanners::SSRFScanner.track_redirects(
76
- request: wrapped_request,
77
- response: Helpers.wrap_response(self)
78
- )
48
+ def self.load_sinks!
49
+ if Aikido::Zen.satisfy "curb", ">= 0.2.3"
50
+ require "curb"
79
51
 
80
- # When libcurl has follow_location set, it will handle redirections
81
- # internally, and expose the "last_effective_url" as the URI that was
82
- # last requested in the redirect chain.
83
- #
84
- # In this case, we can't actually stop the request from happening, but
85
- # we can scan again (now that we know another request happened), to
86
- # stop the response from being exposed to the user. This downgrades
87
- # the SSRF into a blind SSRF, which is better than doing nothing.
88
- if url != last_effective_url
89
- last_effective_request = Helpers.wrap_request(self, url: last_effective_url)
90
-
91
- # Code coverage is disabled here because the else clause is a no-op,
92
- # so there is nothing to cover.
93
- # :nocov:
94
- if context
95
- context["ssrf.request"] = last_effective_request
96
- else
97
- # empty
52
+ ::Curl::Easy.class_eval do
53
+ extend Sinks::DSL
54
+
55
+ sink_around :perform do |original_call|
56
+ wrapped_request = Helpers.wrap_request(self)
57
+
58
+ # Store the request information so the DNS sinks can pick it up.
59
+ context = Aikido::Zen.current_context
60
+ if context
61
+ prev_request = context["ssrf.request"]
62
+ context["ssrf.request"] = wrapped_request
63
+ end
64
+
65
+ connection = OutboundConnection.from_uri(URI(url))
66
+
67
+ Helpers.scan(wrapped_request, connection, "request")
68
+
69
+ response = original_call.call
70
+
71
+ Scanners::SSRFScanner.track_redirects(
72
+ request: wrapped_request,
73
+ response: Helpers.wrap_response(self)
74
+ )
75
+
76
+ # When libcurl has follow_location set, it will handle redirections
77
+ # internally, and expose the "last_effective_url" as the URI that was
78
+ # last requested in the redirect chain.
79
+ #
80
+ # In this case, we can't actually stop the request from happening, but
81
+ # we can scan again (now that we know another request happened), to
82
+ # stop the response from being exposed to the user. This downgrades
83
+ # the SSRF into a blind SSRF, which is better than doing nothing.
84
+ if url != last_effective_url
85
+ last_effective_request = Helpers.wrap_request(self, url: last_effective_url)
86
+
87
+ # Code coverage is disabled here because the else clause is a no-op,
88
+ # so there is nothing to cover.
89
+ # :nocov:
90
+ if context
91
+ context["ssrf.request"] = last_effective_request
92
+ else
93
+ # empty
94
+ end
95
+ # :nocov:
96
+
97
+ connection = OutboundConnection.from_uri(URI(last_effective_url))
98
+
99
+ Helpers.scan(last_effective_request, connection, "request")
100
+ end
101
+
102
+ response
103
+ ensure
104
+ context["ssrf.request"] = prev_request if context
98
105
  end
99
- # :nocov:
100
-
101
- connection = OutboundConnection.from_uri(URI(last_effective_url))
102
-
103
- Helpers.scan(last_effective_request, connection, "request")
104
106
  end
105
-
106
- response
107
- ensure
108
- context["ssrf.request"] = prev_request if context
109
107
  end
110
108
  end
111
109
  end
@@ -7,19 +7,6 @@ module Aikido::Zen
7
7
  module Sinks
8
8
  module EventMachine
9
9
  module HttpRequest
10
- def self.load_sinks!
11
- if Aikido::Zen.satisfy "em-http-request", ">= 1.0"
12
- require "em-http-request"
13
-
14
- ::EventMachine::HttpRequest.use(EventMachine::HttpRequest::Middleware)
15
-
16
- # NOTE: We can't use middleware to intercept requests as we want to ensure any
17
- # modifications to the request from user-supplied middleware are already applied
18
- # before we scan the request.
19
- ::EventMachine::HttpClient.prepend(EventMachine::HttpRequest::HttpClientExtensions)
20
- end
21
- end
22
-
23
10
  SINK = Sinks.add("em-http-request", scanners: [
24
11
  Scanners::SSRFScanner,
25
12
  OutboundConnectionMonitor
@@ -35,26 +22,37 @@ module Aikido::Zen
35
22
  end
36
23
  end
37
24
 
38
- module HttpClientExtensions
39
- extend Sinks::DSL
25
+ def self.load_sinks!
26
+ if Aikido::Zen.satisfy "em-http-request", ">= 1.0"
27
+ require "em-http-request"
40
28
 
41
- sink_before :send_request do
42
- wrapped_request = Scanners::SSRFScanner::Request.new(
43
- verb: req.method.to_s,
44
- uri: URI(req.uri),
45
- headers: req.headers
46
- )
29
+ ::EventMachine::HttpRequest.use(EventMachine::HttpRequest::Middleware)
47
30
 
48
- # Store the request information so the DNS sinks can pick it up.
49
- context = Aikido::Zen.current_context
50
- context["ssrf.request"] = wrapped_request if context
31
+ # NOTE: We can't use middleware to intercept requests as we want to ensure any
32
+ # modifications to the request from user-supplied middleware are already applied
33
+ # before we scan the request.
34
+ ::EventMachine::HttpClient.class_eval do
35
+ extend Sinks::DSL
51
36
 
52
- connection = OutboundConnection.new(
53
- host: req.host,
54
- port: req.port
55
- )
37
+ sink_before :send_request do
38
+ wrapped_request = Scanners::SSRFScanner::Request.new(
39
+ verb: req.method.to_s,
40
+ uri: URI(req.uri),
41
+ headers: req.headers
42
+ )
43
+
44
+ # Store the request information so the DNS sinks can pick it up.
45
+ context = Aikido::Zen.current_context
46
+ context["ssrf.request"] = wrapped_request if context
47
+
48
+ connection = OutboundConnection.new(
49
+ host: req.host,
50
+ port: req.port
51
+ )
56
52
 
57
- Helpers.scan(wrapped_request, connection, "request")
53
+ Helpers.scan(wrapped_request, connection, "request")
54
+ end
55
+ end
58
56
  end
59
57
  end
60
58
 
@@ -6,15 +6,6 @@ require_relative "../outbound_connection_monitor"
6
6
  module Aikido::Zen
7
7
  module Sinks
8
8
  module Excon
9
- def self.load_sinks!
10
- if Aikido::Zen.satisfy "excon", ">= 0.50.0"
11
- require "excon"
12
-
13
- ::Excon::Connection.prepend(ConnectionExtensions)
14
- ::Excon::Middleware::RedirectFollower.prepend(RedirectFollowerExtensions)
15
- end
16
- end
17
-
18
9
  SINK = Sinks.add("excon", scanners: [
19
10
  Scanners::SSRFScanner,
20
11
  OutboundConnectionMonitor
@@ -46,72 +37,78 @@ module Aikido::Zen
46
37
  end
47
38
  end
48
39
 
49
- module ConnectionExtensions
50
- extend Sinks::DSL
40
+ def self.load_sinks!
41
+ if Aikido::Zen.satisfy "excon", ">= 0.50.0"
42
+ require "excon"
43
+
44
+ ::Excon::Connection.class_eval do
45
+ extend Sinks::DSL
51
46
 
52
- sink_around :request do |super_call, params = {}|
53
- request = Helpers.build_request(@data, params)
47
+ sink_around :request do |original_call, params = {}|
48
+ request = Helpers.build_request(@data, params)
54
49
 
55
- # Store the request information so the DNS sinks can pick it up.
56
- context = Aikido::Zen.current_context
57
- if context
58
- prev_request = context["ssrf.request"]
59
- context["ssrf.request"] = request
60
- end
50
+ # Store the request information so the DNS sinks can pick it up.
51
+ context = Aikido::Zen.current_context
52
+ if context
53
+ prev_request = context["ssrf.request"]
54
+ context["ssrf.request"] = request
55
+ end
61
56
 
62
- connection = OutboundConnection.from_uri(request.uri)
57
+ connection = OutboundConnection.from_uri(request.uri)
63
58
 
64
- Helpers.scan(request, connection, "request")
59
+ Helpers.scan(request, connection, "request")
65
60
 
66
- response = super_call.call
61
+ response = original_call.call
67
62
 
68
- Scanners::SSRFScanner.track_redirects(
69
- request: request,
70
- response: Scanners::SSRFScanner::Response.new(
71
- status: response.status,
72
- headers: response.headers.to_h
73
- )
74
- )
63
+ Scanners::SSRFScanner.track_redirects(
64
+ request: request,
65
+ response: Scanners::SSRFScanner::Response.new(
66
+ status: response.status,
67
+ headers: response.headers.to_h
68
+ )
69
+ )
75
70
 
76
- response
77
- rescue Sinks::DSL::PresafeError => err
78
- outer_cause = err.cause
79
- case outer_cause
80
- when ::Excon::Error::Socket
81
- inner_cause = outer_cause.cause
82
- # Excon wraps errors inside the lower level layer. This only happens
83
- # to our scanning exceptions when a request is using RedirectFollower,
84
- # so we unwrap them when it happens so host apps can handle errors
85
- # consistently.
86
- raise inner_cause if inner_cause.is_a?(Aikido::Zen::UnderAttackError)
71
+ response
72
+ rescue Sinks::DSL::PresafeError => err
73
+ outer_cause = err.cause
74
+ case outer_cause
75
+ when ::Excon::Error::Socket
76
+ inner_cause = outer_cause.cause
77
+ # Excon wraps errors inside the lower level layer. This only happens
78
+ # to our scanning exceptions when a request is using RedirectFollower,
79
+ # so we unwrap them when it happens so host apps can handle errors
80
+ # consistently.
81
+ raise inner_cause if inner_cause.is_a?(Aikido::Zen::UnderAttackError)
82
+ end
83
+ raise
84
+ ensure
85
+ context["ssrf.request"] = prev_request if context
86
+ end
87
87
  end
88
- raise
89
- ensure
90
- context["ssrf.request"] = prev_request if context
91
- end
92
- end
93
88
 
94
- module RedirectFollowerExtensions
95
- extend Sinks::DSL
96
-
97
- sink_before :response_call do |datum|
98
- response = datum[:response]
99
-
100
- # Code coverage is disabled here because the else clause is a no-op,
101
- # so there is nothing to cover.
102
- # :nocov:
103
- if !response.nil?
104
- Scanners::SSRFScanner.track_redirects(
105
- request: Helpers.build_request(datum, {}),
106
- response: Scanners::SSRFScanner::Response.new(
107
- status: response[:status],
108
- headers: response[:headers]
109
- )
110
- )
111
- else
112
- # empty
89
+ ::Excon::Middleware::RedirectFollower.class_eval do
90
+ extend Sinks::DSL
91
+
92
+ sink_before :response_call do |datum|
93
+ response = datum[:response]
94
+
95
+ # Code coverage is disabled here because the else clause is a no-op,
96
+ # so there is nothing to cover.
97
+ # :nocov:
98
+ if !response.nil?
99
+ Scanners::SSRFScanner.track_redirects(
100
+ request: Helpers.build_request(datum, {}),
101
+ response: Scanners::SSRFScanner::Response.new(
102
+ status: response[:status],
103
+ headers: response[:headers]
104
+ )
105
+ )
106
+ else
107
+ # empty
108
+ end
109
+ # :nocov:
110
+ end
113
111
  end
114
- # :nocov:
115
112
  end
116
113
  end
117
114
  end