aikido-zen 1.0.1.beta.4-x86_64-linux-musl → 1.0.1.beta.5-x86_64-linux-musl

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: e645ab4d18aeda13f265ca896f40b593f5eadca5a4db9efc72b290fc13e2ca75
4
- data.tar.gz: 7451c8794cc035c7d7741b2564e037328699fd1165cbb7beb49704c2d9e39e6d
3
+ metadata.gz: a8cb66439e682a571b15c7405fef28a3b27a90b248419b3c2c905bdd9e0244b2
4
+ data.tar.gz: 9bcaf684b0fe2a6ce1e24a1601353dcf8a94150a375ece69ad6129109df33a98
5
5
  SHA512:
6
- metadata.gz: 6fac2cae1aa40652da7b7487d0dbc714d08fb5eb60143b7ca748f467842280863c6f4d8f8d0d5f5f6b7f5456684fbbfbca33915a1840e2a26cab9899cfc7f73f
7
- data.tar.gz: 5f9d94f00a4b48e5d97bbf2d0cc178a7e202d9a3fc9dea019f0d4fc54451f42a2a5e0a53e748306ff4e92aec6906870967e5ef59c656c31142d0155715b059a2
6
+ metadata.gz: 77073b3af1244161c7241eda17b77905c12a3835239313b06512116bff1a24223f8098079a6671d8941df1dd0da36a3e050be93054165f4378629a6e1156cc27
7
+ data.tar.gz: de9918d2afc2498c5ffb9312a54d8c7cf6f6a0b653a539c40b2c3e287852b259c085d5f9aac854957729efe9d5cc23891f807ee3f8178b229a2cbbe9315fe765
@@ -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
@@ -3,18 +3,6 @@
3
3
  module Aikido::Zen
4
4
  module Sinks
5
5
  module File
6
- def self.load_sinks!
7
- # Create a copy of the original method for internal use only to prevent
8
- # recursion in PathTraversalScanner.
9
- #
10
- # IMPORTANT: The alias must be created before the method is overridden,
11
- # when the extensions are prepended.
12
- ::File.singleton_class.alias_method(:expand_path__internal_for_aikido_zen, :expand_path)
13
-
14
- ::File.singleton_class.prepend(FileClassExtensions)
15
- ::File.prepend(FileExtensions)
16
- end
17
-
18
6
  SINK = Sinks.add("File", scanners: [Scanners::PathTraversalScanner])
19
7
 
20
8
  module Helpers
@@ -26,87 +14,95 @@ module Aikido::Zen
26
14
  end
27
15
  end
28
16
 
29
- module FileClassExtensions
30
- extend Sinks::DSL
17
+ def self.load_sinks!
18
+ ::File.singleton_class.class_eval do
19
+ extend Sinks::DSL
31
20
 
32
- sink_before :open do |path|
33
- Helpers.scan(path, "open")
34
- end
21
+ # Create a copy of the original method for internal use only to prevent
22
+ # recursion in PathTraversalScanner.
23
+ #
24
+ # IMPORTANT: The alias must be created before the method is overridden.
25
+ alias_method :expand_path__internal_for_aikido_zen, :expand_path
35
26
 
36
- sink_before :read do |path|
37
- Helpers.scan(path, "read")
38
- end
27
+ sink_before :open do |path|
28
+ Helpers.scan(path, "open")
29
+ end
39
30
 
40
- sink_before :write do |path|
41
- Helpers.scan(path, "write")
42
- end
31
+ sink_before :read do |path|
32
+ Helpers.scan(path, "read")
33
+ end
43
34
 
44
- sink_before :truncate do |file_name|
45
- Helpers.scan(file_name, "truncate")
46
- end
35
+ sink_before :write do |path|
36
+ Helpers.scan(path, "write")
37
+ end
47
38
 
48
- sink_before :rename do |old_name, new_name|
49
- Helpers.scan(old_name, "rename")
50
- Helpers.scan(new_name, "rename")
51
- end
39
+ sink_before :truncate do |file_name|
40
+ Helpers.scan(file_name, "truncate")
41
+ end
52
42
 
53
- sink_before :unlink do |*file_names|
54
- file_names.each do |file_name|
55
- Helpers.scan(file_name, "unlink")
43
+ sink_before :rename do |old_name, new_name|
44
+ Helpers.scan(old_name, "rename")
45
+ Helpers.scan(new_name, "rename")
56
46
  end
57
- end
58
47
 
59
- sink_before :delete do |*file_names|
60
- file_names.each do |file_name|
61
- Helpers.scan(file_name, "delete")
48
+ sink_before :unlink do |*file_names|
49
+ file_names.each do |file_name|
50
+ Helpers.scan(file_name, "unlink")
51
+ end
62
52
  end
63
- end
64
53
 
65
- sink_before :symlink do |old_name, new_name|
66
- Helpers.scan(old_name, "symlink")
67
- Helpers.scan(new_name, "symlink")
68
- end
54
+ sink_before :delete do |*file_names|
55
+ file_names.each do |file_name|
56
+ Helpers.scan(file_name, "delete")
57
+ end
58
+ end
69
59
 
70
- sink_before :chmod do |_mode_int, *file_names|
71
- file_names.each do |file_name|
72
- Helpers.scan(file_name, "chmod")
60
+ sink_before :symlink do |old_name, new_name|
61
+ Helpers.scan(old_name, "symlink")
62
+ Helpers.scan(new_name, "symlink")
73
63
  end
74
- end
75
64
 
76
- sink_before :chown do |_owner_int, group_int, *file_names|
77
- file_names.each do |file_name|
78
- Helpers.scan(file_name, "chown")
65
+ sink_before :chmod do |_mode_int, *file_names|
66
+ file_names.each do |file_name|
67
+ Helpers.scan(file_name, "chmod")
68
+ end
79
69
  end
80
- end
81
70
 
82
- sink_before :utime do |_atime, _mtime, *file_names|
83
- file_names.each do |file_name|
84
- Helpers.scan(file_name, "utime")
71
+ sink_before :chown do |_owner_int, group_int, *file_names|
72
+ file_names.each do |file_name|
73
+ Helpers.scan(file_name, "chown")
74
+ end
85
75
  end
86
- end
87
76
 
88
- sink_after :join do |result|
89
- Helpers.scan(result, "join")
90
- end
77
+ sink_before :utime do |_atime, _mtime, *file_names|
78
+ file_names.each do |file_name|
79
+ Helpers.scan(file_name, "utime")
80
+ end
81
+ end
91
82
 
92
- sink_before :expand_path do |file_name|
93
- Helpers.scan(file_name, "expand_path")
94
- end
83
+ sink_after :join do |result|
84
+ Helpers.scan(result, "join")
85
+ end
95
86
 
96
- sink_before :realpath do |file_name|
97
- Helpers.scan(file_name, "realpath")
98
- end
87
+ sink_before :expand_path do |file_name|
88
+ Helpers.scan(file_name, "expand_path")
89
+ end
90
+
91
+ sink_before :realpath do |file_name|
92
+ Helpers.scan(file_name, "realpath")
93
+ end
99
94
 
100
- sink_before :realdirpath do |file_name|
101
- Helpers.scan(file_name, "realdirpath")
95
+ sink_before :realdirpath do |file_name|
96
+ Helpers.scan(file_name, "realdirpath")
97
+ end
102
98
  end
103
- end
104
99
 
105
- module FileExtensions
106
- extend Sinks::DSL
100
+ ::File.class_eval do
101
+ extend Sinks::DSL
107
102
 
108
- sink_before :initialize do |path|
109
- Helpers.scan(path, "new")
103
+ sink_before :initialize do |path|
104
+ Helpers.scan(path, "new")
105
+ end
110
106
  end
111
107
  end
112
108
  end