aikido-zen 1.0.1.beta.4-x86_64-linux-musl → 1.0.2.beta.1-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.
@@ -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
@@ -6,14 +6,6 @@ require_relative "../outbound_connection_monitor"
6
6
  module Aikido::Zen
7
7
  module Sinks
8
8
  module HTTP
9
- def self.load_sinks!
10
- if Aikido::Zen.satisfy "http", ">= 1.0"
11
- require "http"
12
-
13
- ::HTTP::Client.prepend(ClientExtensions)
14
- end
15
- end
16
-
17
9
  SINK = Sinks.add("http", scanners: [
18
10
  Scanners::SSRFScanner,
19
11
  OutboundConnectionMonitor
@@ -59,33 +51,39 @@ module Aikido::Zen
59
51
  end
60
52
  end
61
53
 
62
- module ClientExtensions
63
- extend Sinks::DSL
54
+ def self.load_sinks!
55
+ if Aikido::Zen.satisfy "http", ">= 1.0"
56
+ require "http"
64
57
 
65
- sink_around :perform do |super_call, req|
66
- wrapped_request = Helpers.wrap_request(req)
58
+ ::HTTP::Client.class_eval do
59
+ extend Sinks::DSL
67
60
 
68
- # Store the request information so the DNS sinks can pick it up.
69
- context = Aikido::Zen.current_context
70
- if context
71
- prev_request = context["ssrf.request"]
72
- context["ssrf.request"] = wrapped_request
73
- end
61
+ sink_around :perform do |original_call, req|
62
+ wrapped_request = Helpers.wrap_request(req)
74
63
 
75
- connection = Helpers.build_outbound(req)
64
+ # Store the request information so the DNS sinks can pick it up.
65
+ context = Aikido::Zen.current_context
66
+ if context
67
+ prev_request = context["ssrf.request"]
68
+ context["ssrf.request"] = wrapped_request
69
+ end
76
70
 
77
- Helpers.scan(wrapped_request, connection, "request")
71
+ connection = Helpers.build_outbound(req)
78
72
 
79
- response = super_call.call
73
+ Helpers.scan(wrapped_request, connection, "request")
80
74
 
81
- Scanners::SSRFScanner.track_redirects(
82
- request: wrapped_request,
83
- response: Helpers.wrap_response(response)
84
- )
75
+ response = original_call.call
76
+
77
+ Scanners::SSRFScanner.track_redirects(
78
+ request: wrapped_request,
79
+ response: Helpers.wrap_response(response)
80
+ )
85
81
 
86
- response
87
- ensure
88
- context["ssrf.request"] = prev_request if context
82
+ response
83
+ ensure
84
+ context["ssrf.request"] = prev_request if context
85
+ end
86
+ end
89
87
  end
90
88
  end
91
89
  end
@@ -6,14 +6,6 @@ require_relative "../outbound_connection_monitor"
6
6
  module Aikido::Zen
7
7
  module Sinks
8
8
  module HTTPClient
9
- def self.load_sinks!
10
- if Aikido::Zen.satisfy "httpclient", ">= 2.0"
11
- require "httpclient"
12
-
13
- ::HTTPClient.prepend(HTTPClient::HTTPClientExtensions)
14
- end
15
- end
16
-
17
9
  SINK = Sinks.add("httpclient", scanners: [
18
10
  Scanners::SSRFScanner,
19
11
  OutboundConnectionMonitor
@@ -66,28 +58,34 @@ module Aikido::Zen
66
58
  end
67
59
  end
68
60
 
69
- module HTTPClientExtensions
70
- extend Sinks::DSL
71
-
72
- private
73
-
74
- sink_around :do_get_block do |super_call, req|
75
- Helpers.sink(req, &super_call)
76
- end
77
-
78
- sink_around :do_get_stream do |super_call, req|
79
- Helpers.sink(req, &super_call)
80
- end
61
+ def self.load_sinks!
62
+ if Aikido::Zen.satisfy "httpclient", ">= 2.0"
63
+ require "httpclient"
81
64
 
82
- sink_after :do_get_header do |_result, req, res, _sess|
83
- # Code coverage is disabled here because `do_get_header` is not called,
84
- # because WebMock does not mock it.
85
- # :nocov:
86
- Scanners::SSRFScanner.track_redirects(
87
- request: Helpers.wrap_request(req),
88
- response: Helpers.wrap_response(res)
89
- )
90
- # :nocov:
65
+ ::HTTPClient.class_eval do
66
+ extend Sinks::DSL
67
+
68
+ private
69
+
70
+ sink_around :do_get_block do |original_call, req|
71
+ Helpers.sink(req, &original_call)
72
+ end
73
+
74
+ sink_around :do_get_stream do |original_call, req|
75
+ Helpers.sink(req, &original_call)
76
+ end
77
+
78
+ sink_after :do_get_header do |_result, req, res, _sess|
79
+ # Code coverage is disabled here because `do_get_header` is not called,
80
+ # because WebMock does not mock it.
81
+ # :nocov:
82
+ Scanners::SSRFScanner.track_redirects(
83
+ request: Helpers.wrap_request(req),
84
+ response: Helpers.wrap_response(res)
85
+ )
86
+ # :nocov:
87
+ end
88
+ end
91
89
  end
92
90
  end
93
91
  end
@@ -6,14 +6,6 @@ require_relative "../outbound_connection_monitor"
6
6
  module Aikido::Zen
7
7
  module Sinks
8
8
  module HTTPX
9
- def self.load_sinks!
10
- if Aikido::Zen.satisfy "httpx", ">= 1.1.3"
11
- require "httpx"
12
-
13
- ::HTTPX::Session.prepend(HTTPX::SessionExtensions)
14
- end
15
- end
16
-
17
9
  SINK = Sinks.add("httpx", scanners: [
18
10
  Scanners::SSRFScanner,
19
11
  OutboundConnectionMonitor
@@ -44,33 +36,39 @@ module Aikido::Zen
44
36
  end
45
37
  end
46
38
 
47
- module SessionExtensions
48
- extend Sinks::DSL
39
+ def self.load_sinks!
40
+ if Aikido::Zen.satisfy "httpx", ">= 1.1.3"
41
+ require "httpx"
49
42
 
50
- sink_around :send_request do |super_call, request|
51
- wrapped_request = Helpers.wrap_request(request)
43
+ ::HTTPX::Session.class_eval do
44
+ extend Sinks::DSL
52
45
 
53
- # Store the request information so the DNS sinks can pick it up.
54
- context = Aikido::Zen.current_context
55
- if context
56
- prev_request = context["ssrf.request"]
57
- context["ssrf.request"] = wrapped_request
58
- end
46
+ sink_around :send_request do |original_call, request|
47
+ wrapped_request = Helpers.wrap_request(request)
59
48
 
60
- connection = OutboundConnection.from_uri(request.uri)
49
+ # Store the request information so the DNS sinks can pick it up.
50
+ context = Aikido::Zen.current_context
51
+ if context
52
+ prev_request = context["ssrf.request"]
53
+ context["ssrf.request"] = wrapped_request
54
+ end
61
55
 
62
- Helpers.scan(wrapped_request, connection, "request")
56
+ connection = OutboundConnection.from_uri(request.uri)
63
57
 
64
- request.on(:response) do |response|
65
- Scanners::SSRFScanner.track_redirects(
66
- request: wrapped_request,
67
- response: Helpers.wrap_response(response)
68
- )
69
- end
58
+ Helpers.scan(wrapped_request, connection, "request")
59
+
60
+ request.on(:response) do |response|
61
+ Scanners::SSRFScanner.track_redirects(
62
+ request: wrapped_request,
63
+ response: Helpers.wrap_response(response)
64
+ )
65
+ end
70
66
 
71
- super_call.call
72
- ensure
73
- context["ssrf.request"] = prev_request if context
67
+ original_call.call
68
+ ensure
69
+ context["ssrf.request"] = prev_request if context
70
+ end
71
+ end
74
72
  end
75
73
  end
76
74
  end
@@ -3,11 +3,6 @@
3
3
  module Aikido::Zen
4
4
  module Sinks
5
5
  module Kernel
6
- def self.load_sinks!
7
- ::Kernel.singleton_class.prepend(KernelExtensions)
8
- ::Kernel.prepend(KernelExtensions)
9
- end
10
-
11
6
  SINK = Sinks.add("Kernel", scanners: [Scanners::ShellInjectionScanner])
12
7
 
13
8
  module Helpers
@@ -16,14 +11,18 @@ module Aikido::Zen
16
11
  end
17
12
  end
18
13
 
19
- module KernelExtensions
20
- extend Sinks::DSL
14
+ def self.load_sinks!
15
+ [::Kernel.singleton_class, ::Kernel].each do |klass|
16
+ klass.class_eval do
17
+ extend Sinks::DSL
21
18
 
22
- %i[system spawn].each do |method_name|
23
- sink_before method_name do |*args|
24
- # Remove the optional environment argument before the command-line.
25
- args.shift if args.first.is_a?(Hash)
26
- Helpers.scan(args.first, method_name)
19
+ %i[system spawn].each do |method_name|
20
+ sink_before method_name do |*args|
21
+ # Remove the optional environment argument before the command-line.
22
+ args.shift if args.first.is_a?(Hash)
23
+ Helpers.scan(args.first, method_name)
24
+ end
25
+ end
27
26
  end
28
27
  end
29
28
  end
@@ -3,14 +3,6 @@
3
3
  module Aikido::Zen
4
4
  module Sinks
5
5
  module Mysql2
6
- def self.load_sinks!
7
- if Aikido::Zen.satisfy "mysql2"
8
- require "mysql2"
9
-
10
- ::Mysql2::Client.prepend(ClientExtensions)
11
- end
12
- end
13
-
14
6
  SINK = Sinks.add("mysql2", scanners: [Scanners::SQLInjectionScanner])
15
7
 
16
8
  module Helpers
@@ -19,11 +11,17 @@ module Aikido::Zen
19
11
  end
20
12
  end
21
13
 
22
- module ClientExtensions
23
- extend Sinks::DSL
14
+ def self.load_sinks!
15
+ if Aikido::Zen.satisfy "mysql2"
16
+ require "mysql2"
17
+
18
+ ::Mysql2::Client.class_eval do
19
+ extend Sinks::DSL
24
20
 
25
- sink_before :query do |sql|
26
- Helpers.scan(sql, "query")
21
+ sink_before :query do |sql|
22
+ Helpers.scan(sql, "query")
23
+ end
24
+ end
27
25
  end
28
26
  end
29
27
  end