aikido-zen 1.0.2.beta.5-x86_64-mingw-64 → 1.0.2.beta.7-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 +4 -4
- data/.simplecov +6 -0
- data/README.md +1 -0
- data/benchmarks/README.md +0 -1
- data/benchmarks/rails7.1_benchmark.js +1 -0
- data/benchmarks/rails7.1_sql_injection.js +52 -20
- data/docs/rails.md +5 -7
- data/lib/aikido/zen/actor.rb +34 -4
- data/lib/aikido/zen/agent/heartbeats_manager.rb +5 -5
- data/lib/aikido/zen/agent.rb +17 -15
- data/lib/aikido/zen/collector/event.rb +209 -0
- data/lib/aikido/zen/collector/routes.rb +13 -8
- data/lib/aikido/zen/collector/stats.rb +16 -19
- data/lib/aikido/zen/collector/users.rb +3 -1
- data/lib/aikido/zen/collector.rb +94 -29
- data/lib/aikido/zen/config.rb +4 -10
- data/lib/aikido/zen/context.rb +8 -7
- data/lib/aikido/zen/detached_agent/agent.rb +28 -27
- data/lib/aikido/zen/detached_agent/front_object.rb +10 -6
- data/lib/aikido/zen/internals.rb +23 -3
- data/lib/aikido/zen/libzen-v0.1.48-x86_64-mingw-64.dll +0 -0
- data/lib/aikido/zen/middleware/fork_detector.rb +23 -0
- data/lib/aikido/zen/middleware/request_tracker.rb +1 -1
- data/lib/aikido/zen/outbound_connection.rb +7 -0
- data/lib/aikido/zen/rails_engine.rb +2 -6
- data/lib/aikido/zen/route.rb +7 -0
- data/lib/aikido/zen/runtime_settings.rb +1 -1
- data/lib/aikido/zen/scanners/path_traversal/helpers.rb +10 -7
- data/lib/aikido/zen/scanners/path_traversal_scanner.rb +2 -2
- data/lib/aikido/zen/sink.rb +1 -1
- data/lib/aikido/zen/sinks/file.rb +43 -4
- data/lib/aikido/zen/sinks/kernel.rb +1 -1
- data/lib/aikido/zen/version.rb +2 -2
- data/lib/aikido/zen.rb +8 -9
- metadata +6 -3
- data/lib/aikido/zen/libzen-v0.1.39-x86_64-mingw-64.dll +0 -0
|
@@ -4,7 +4,8 @@ module Aikido::Zen
|
|
|
4
4
|
module Scanners
|
|
5
5
|
module PathTraversal
|
|
6
6
|
DANGEROUS_PATH_PARTS = ["../", "..\\"]
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
LINUX_PATH_STARTS = [
|
|
8
9
|
"/bin/",
|
|
9
10
|
"/boot/",
|
|
10
11
|
"/dev/",
|
|
@@ -26,10 +27,12 @@ module Aikido::Zen
|
|
|
26
27
|
"/var/"
|
|
27
28
|
]
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
WINDOWS_PATH_STARTS = ["c:/", "c:\\"]
|
|
31
|
+
|
|
32
|
+
DANGEROUS_PATH_STARTS = LINUX_PATH_STARTS + WINDOWS_PATH_STARTS
|
|
30
33
|
|
|
31
34
|
module Helpers
|
|
32
|
-
def self.
|
|
35
|
+
def self.include_unsafe_path_parts?(filepath)
|
|
33
36
|
DANGEROUS_PATH_PARTS.each do |dangerous_part|
|
|
34
37
|
return true if filepath.include?(dangerous_part)
|
|
35
38
|
end
|
|
@@ -37,7 +40,7 @@ module Aikido::Zen
|
|
|
37
40
|
false
|
|
38
41
|
end
|
|
39
42
|
|
|
40
|
-
def self.
|
|
43
|
+
def self.start_with_unsafe_path?(filepath, user_input)
|
|
41
44
|
# Check if path is relative (not absolute or drive letter path)
|
|
42
45
|
# Required because `expand_path` will build absolute paths from relative paths
|
|
43
46
|
return false if Pathname.new(filepath).relative? || Pathname.new(user_input).relative?
|
|
@@ -51,12 +54,12 @@ module Aikido::Zen
|
|
|
51
54
|
# to prevent false positives.
|
|
52
55
|
# e.g., if user input is /etc/ and the path is /etc/passwd, we don't want to flag it,
|
|
53
56
|
# as long as the user input does not contain a subdirectory or filename
|
|
54
|
-
if user_input == dangerous_start || user_input == dangerous_start.chomp("/")
|
|
55
|
-
|
|
56
|
-
end
|
|
57
|
+
return false if user_input == dangerous_start || user_input == dangerous_start.chomp("/")
|
|
58
|
+
|
|
57
59
|
return true
|
|
58
60
|
end
|
|
59
61
|
end
|
|
62
|
+
|
|
60
63
|
false
|
|
61
64
|
end
|
|
62
65
|
end
|
|
@@ -51,12 +51,12 @@ module Aikido::Zen
|
|
|
51
51
|
# We ignore cases where the user input is not part of the file path.
|
|
52
52
|
return false unless @filepath.include?(@input)
|
|
53
53
|
|
|
54
|
-
if PathTraversal::Helpers.
|
|
54
|
+
if PathTraversal::Helpers.include_unsafe_path_parts?(@filepath) && PathTraversal::Helpers.include_unsafe_path_parts?(@input)
|
|
55
55
|
return true
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
# Check for absolute path traversal
|
|
59
|
-
PathTraversal::Helpers.
|
|
59
|
+
PathTraversal::Helpers.start_with_unsafe_path?(@filepath, @input)
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
62
|
end
|
data/lib/aikido/zen/sink.rb
CHANGED
|
@@ -18,11 +18,12 @@ module Aikido::Zen
|
|
|
18
18
|
::File.singleton_class.class_eval do
|
|
19
19
|
extend Sinks::DSL
|
|
20
20
|
|
|
21
|
-
# Create a copy of the original
|
|
21
|
+
# Create a copy of the original methods for internal use only to prevent
|
|
22
22
|
# recursion in PathTraversalScanner.
|
|
23
23
|
#
|
|
24
|
-
# IMPORTANT: The
|
|
24
|
+
# IMPORTANT: The aliases must be created before the method is overridden.
|
|
25
25
|
alias_method :expand_path__internal_for_aikido_zen, :expand_path
|
|
26
|
+
alias_method :join__internal_for_aikido_zen, :join
|
|
26
27
|
|
|
27
28
|
sink_before :open do |path|
|
|
28
29
|
Helpers.scan(path, "open")
|
|
@@ -80,8 +81,46 @@ module Aikido::Zen
|
|
|
80
81
|
end
|
|
81
82
|
end
|
|
82
83
|
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
def join(*args, **kwargs, &blk)
|
|
85
|
+
# IMPORTANT: THE BEHAVIOR OF THIS METHOD IS CHANGED!
|
|
86
|
+
#
|
|
87
|
+
# File.join has undocumented behavior:
|
|
88
|
+
#
|
|
89
|
+
# File.join recursively joins nested string arrays.
|
|
90
|
+
#
|
|
91
|
+
# This prevents path traversal detection when an array originates
|
|
92
|
+
# from user input that was assumed to be a string.
|
|
93
|
+
#
|
|
94
|
+
# This undocumented behavior has been restricted to support path
|
|
95
|
+
# traversal detection.
|
|
96
|
+
#
|
|
97
|
+
# File.join no longer joins nested string arrays, but still accepts
|
|
98
|
+
# a single string array argument.
|
|
99
|
+
|
|
100
|
+
# File.join is often incorrectly called with a single array argument.
|
|
101
|
+
#
|
|
102
|
+
# i.e.
|
|
103
|
+
#
|
|
104
|
+
# File.join(["prefix", "filename"])
|
|
105
|
+
#
|
|
106
|
+
# This is considered acceptable.
|
|
107
|
+
#
|
|
108
|
+
# Calling File.join with a single string argument returns the string
|
|
109
|
+
# argument itself, having no practical effect. Therefore, it can be
|
|
110
|
+
# presumed that if File.join is called with a single array argument
|
|
111
|
+
# then this was its intended usage, and the array did not originate
|
|
112
|
+
# from user input that was assumed to be a string.
|
|
113
|
+
strings = args
|
|
114
|
+
strings = args.first if args.size == 1 && args.first.is_a?(Array)
|
|
115
|
+
strings.each do |string|
|
|
116
|
+
raise TypeError.new("Zen prevented implicit conversion of Array to String") if string.is_a?(Array)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
result = join__internal_for_aikido_zen(*args, **kwargs, &blk)
|
|
120
|
+
Sinks::DSL.safe do
|
|
121
|
+
Helpers.scan(result, "join")
|
|
122
|
+
end
|
|
123
|
+
result
|
|
85
124
|
end
|
|
86
125
|
|
|
87
126
|
sink_before :expand_path do |file_name|
|
|
@@ -16,7 +16,7 @@ module Aikido::Zen
|
|
|
16
16
|
klass.class_eval do
|
|
17
17
|
extend Sinks::DSL
|
|
18
18
|
|
|
19
|
-
%i[system spawn].each do |method_name|
|
|
19
|
+
%i[system spawn `].each do |method_name|
|
|
20
20
|
sink_before method_name do |*args|
|
|
21
21
|
# Remove the optional environment argument before the command-line.
|
|
22
22
|
args.shift if args.first.is_a?(Hash)
|
data/lib/aikido/zen/version.rb
CHANGED
data/lib/aikido/zen.rb
CHANGED
|
@@ -11,10 +11,11 @@ require_relative "zen/agent"
|
|
|
11
11
|
require_relative "zen/api_client"
|
|
12
12
|
require_relative "zen/context"
|
|
13
13
|
require_relative "zen/detached_agent"
|
|
14
|
-
require_relative "zen/middleware/check_allowed_addresses"
|
|
15
14
|
require_relative "zen/middleware/middleware"
|
|
16
|
-
require_relative "zen/middleware/
|
|
15
|
+
require_relative "zen/middleware/fork_detector"
|
|
17
16
|
require_relative "zen/middleware/set_context"
|
|
17
|
+
require_relative "zen/middleware/check_allowed_addresses"
|
|
18
|
+
require_relative "zen/middleware/request_tracker"
|
|
18
19
|
require_relative "zen/outbound_connection"
|
|
19
20
|
require_relative "zen/outbound_connection_monitor"
|
|
20
21
|
require_relative "zen/runtime_settings"
|
|
@@ -36,8 +37,6 @@ module Aikido
|
|
|
36
37
|
return
|
|
37
38
|
end
|
|
38
39
|
|
|
39
|
-
return unless config.protect?
|
|
40
|
-
|
|
41
40
|
unless load_sources! && load_sinks!
|
|
42
41
|
config.logger.warn("Zen could not find any supported libraries or frameworks. Visit https://github.com/AikidoSec/firewall-ruby for more information.")
|
|
43
42
|
return
|
|
@@ -87,12 +86,10 @@ module Aikido
|
|
|
87
86
|
# Manages runtime metrics extracted from your app, which are uploaded to the
|
|
88
87
|
# Aikido servers if configured to do so.
|
|
89
88
|
def self.collector
|
|
90
|
-
check_and_handle_fork
|
|
91
89
|
@collector ||= Collector.new
|
|
92
90
|
end
|
|
93
91
|
|
|
94
92
|
def self.detached_agent
|
|
95
|
-
check_and_handle_fork
|
|
96
93
|
@detached_agent ||= DetachedAgent::Agent.new
|
|
97
94
|
end
|
|
98
95
|
|
|
@@ -231,9 +228,7 @@ module Aikido
|
|
|
231
228
|
end
|
|
232
229
|
|
|
233
230
|
def check_and_handle_fork
|
|
234
|
-
if has_forked
|
|
235
|
-
@detached_agent&.handle_fork
|
|
236
|
-
end
|
|
231
|
+
handle_fork if has_forked
|
|
237
232
|
end
|
|
238
233
|
|
|
239
234
|
def has_forked
|
|
@@ -241,6 +236,10 @@ module Aikido
|
|
|
241
236
|
@pid = Process.pid
|
|
242
237
|
pid_changed
|
|
243
238
|
end
|
|
239
|
+
|
|
240
|
+
def handle_fork
|
|
241
|
+
@detached_agent&.handle_fork
|
|
242
|
+
end
|
|
244
243
|
end
|
|
245
244
|
end
|
|
246
245
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: aikido-zen
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.2.beta.
|
|
4
|
+
version: 1.0.2.beta.7
|
|
5
5
|
platform: x86_64-mingw-64
|
|
6
6
|
authors:
|
|
7
7
|
- Aikido Security
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-10-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: concurrent-ruby
|
|
@@ -71,6 +71,7 @@ files:
|
|
|
71
71
|
- README.md
|
|
72
72
|
- Rakefile
|
|
73
73
|
- benchmarks/README.md
|
|
74
|
+
- benchmarks/rails7.1_benchmark.js
|
|
74
75
|
- benchmarks/rails7.1_sql_injection.js
|
|
75
76
|
- docs/banner.svg
|
|
76
77
|
- docs/config.md
|
|
@@ -86,6 +87,7 @@ files:
|
|
|
86
87
|
- lib/aikido/zen/background_worker.rb
|
|
87
88
|
- lib/aikido/zen/capped_collections.rb
|
|
88
89
|
- lib/aikido/zen/collector.rb
|
|
90
|
+
- lib/aikido/zen/collector/event.rb
|
|
89
91
|
- lib/aikido/zen/collector/hosts.rb
|
|
90
92
|
- lib/aikido/zen/collector/routes.rb
|
|
91
93
|
- lib/aikido/zen/collector/sink_stats.rb
|
|
@@ -102,8 +104,9 @@ files:
|
|
|
102
104
|
- lib/aikido/zen/errors.rb
|
|
103
105
|
- lib/aikido/zen/event.rb
|
|
104
106
|
- lib/aikido/zen/internals.rb
|
|
105
|
-
- lib/aikido/zen/libzen-v0.1.
|
|
107
|
+
- lib/aikido/zen/libzen-v0.1.48-x86_64-mingw-64.dll
|
|
106
108
|
- lib/aikido/zen/middleware/check_allowed_addresses.rb
|
|
109
|
+
- lib/aikido/zen/middleware/fork_detector.rb
|
|
107
110
|
- lib/aikido/zen/middleware/middleware.rb
|
|
108
111
|
- lib/aikido/zen/middleware/rack_throttler.rb
|
|
109
112
|
- lib/aikido/zen/middleware/request_tracker.rb
|
|
Binary file
|