aikido-zen 1.0.1.beta.4-arm64-linux-musl → 1.0.2-arm64-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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.simplecov +6 -0
  3. data/README.md +2 -0
  4. data/benchmarks/README.md +0 -1
  5. data/benchmarks/rails7.1_benchmark.js +1 -0
  6. data/benchmarks/rails7.1_sql_injection.js +52 -20
  7. data/docs/config.md +9 -1
  8. data/docs/proxy.md +10 -0
  9. data/docs/rails.md +55 -13
  10. data/docs/troubleshooting.md +62 -0
  11. data/lib/aikido/zen/actor.rb +34 -4
  12. data/lib/aikido/zen/agent/heartbeats_manager.rb +5 -5
  13. data/lib/aikido/zen/agent.rb +19 -17
  14. data/lib/aikido/zen/attack.rb +19 -9
  15. data/lib/aikido/zen/attack_wave/helpers.rb +457 -0
  16. data/lib/aikido/zen/attack_wave.rb +88 -0
  17. data/lib/aikido/zen/cache.rb +91 -0
  18. data/lib/aikido/zen/capped_collections.rb +22 -4
  19. data/lib/aikido/zen/collector/event.rb +238 -0
  20. data/lib/aikido/zen/collector/hosts.rb +16 -1
  21. data/lib/aikido/zen/collector/routes.rb +13 -8
  22. data/lib/aikido/zen/collector/stats.rb +33 -22
  23. data/lib/aikido/zen/collector/users.rb +5 -3
  24. data/lib/aikido/zen/collector.rb +107 -28
  25. data/lib/aikido/zen/config.rb +54 -21
  26. data/lib/aikido/zen/context/rack_request.rb +3 -0
  27. data/lib/aikido/zen/context/rails_request.rb +3 -0
  28. data/lib/aikido/zen/context.rb +42 -9
  29. data/lib/aikido/zen/detached_agent/agent.rb +28 -27
  30. data/lib/aikido/zen/detached_agent/front_object.rb +10 -6
  31. data/lib/aikido/zen/detached_agent/server.rb +63 -26
  32. data/lib/aikido/zen/event.rb +47 -2
  33. data/lib/aikido/zen/helpers.rb +24 -0
  34. data/lib/aikido/zen/internals.rb +23 -3
  35. data/lib/aikido/zen/libzen-v0.1.48-arm64-linux-musl.so +0 -0
  36. data/lib/aikido/zen/middleware/{check_allowed_addresses.rb → allowed_address_checker.rb} +1 -1
  37. data/lib/aikido/zen/middleware/attack_wave_protector.rb +46 -0
  38. data/lib/aikido/zen/middleware/{set_context.rb → context_setter.rb} +1 -1
  39. data/lib/aikido/zen/middleware/fork_detector.rb +23 -0
  40. data/lib/aikido/zen/middleware/rack_throttler.rb +3 -1
  41. data/lib/aikido/zen/middleware/request_tracker.rb +9 -4
  42. data/lib/aikido/zen/outbound_connection.rb +18 -1
  43. data/lib/aikido/zen/payload.rb +1 -1
  44. data/lib/aikido/zen/rails_engine.rb +5 -8
  45. data/lib/aikido/zen/request/rails_router.rb +17 -2
  46. data/lib/aikido/zen/request.rb +21 -36
  47. data/lib/aikido/zen/route.rb +57 -0
  48. data/lib/aikido/zen/runtime_settings/endpoints.rb +37 -8
  49. data/lib/aikido/zen/runtime_settings.rb +6 -5
  50. data/lib/aikido/zen/scanners/path_traversal/helpers.rb +10 -7
  51. data/lib/aikido/zen/scanners/path_traversal_scanner.rb +5 -4
  52. data/lib/aikido/zen/scanners/shell_injection_scanner.rb +3 -2
  53. data/lib/aikido/zen/scanners/sql_injection_scanner.rb +3 -2
  54. data/lib/aikido/zen/scanners/ssrf_scanner.rb +2 -1
  55. data/lib/aikido/zen/scanners/stored_ssrf_scanner.rb +8 -2
  56. data/lib/aikido/zen/sink.rb +1 -1
  57. data/lib/aikido/zen/sinks/action_controller.rb +3 -1
  58. data/lib/aikido/zen/sinks/async_http.rb +40 -42
  59. data/lib/aikido/zen/sinks/curb.rb +56 -58
  60. data/lib/aikido/zen/sinks/em_http.rb +27 -29
  61. data/lib/aikido/zen/sinks/excon.rb +62 -65
  62. data/lib/aikido/zen/sinks/file.rb +108 -71
  63. data/lib/aikido/zen/sinks/http.rb +26 -28
  64. data/lib/aikido/zen/sinks/httpclient.rb +27 -29
  65. data/lib/aikido/zen/sinks/httpx.rb +27 -29
  66. data/lib/aikido/zen/sinks/kernel.rb +11 -12
  67. data/lib/aikido/zen/sinks/mysql2.rb +10 -12
  68. data/lib/aikido/zen/sinks/net_http.rb +25 -27
  69. data/lib/aikido/zen/sinks/patron.rb +56 -58
  70. data/lib/aikido/zen/sinks/pg.rb +23 -25
  71. data/lib/aikido/zen/sinks/resolv.rb +21 -21
  72. data/lib/aikido/zen/sinks/socket.rb +17 -12
  73. data/lib/aikido/zen/sinks/sqlite3.rb +18 -21
  74. data/lib/aikido/zen/sinks/trilogy.rb +10 -12
  75. data/lib/aikido/zen/sinks.rb +1 -4
  76. data/lib/aikido/zen/sinks_dsl.rb +39 -15
  77. data/lib/aikido/zen/system_info.rb +1 -5
  78. data/lib/aikido/zen/version.rb +2 -2
  79. data/lib/aikido/zen.rb +78 -16
  80. data/tasklib/bench.rake +1 -1
  81. data/tasklib/libzen.rake +1 -0
  82. metadata +15 -5
  83. data/lib/aikido/zen/libzen-v0.1.39-arm64-linux-musl.so +0 -0
data/lib/aikido/zen.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "zen/helpers"
3
4
  require_relative "zen/version"
4
5
  require_relative "zen/errors"
5
6
  require_relative "zen/actor"
@@ -11,14 +12,17 @@ require_relative "zen/agent"
11
12
  require_relative "zen/api_client"
12
13
  require_relative "zen/context"
13
14
  require_relative "zen/detached_agent"
14
- require_relative "zen/middleware/check_allowed_addresses"
15
15
  require_relative "zen/middleware/middleware"
16
+ require_relative "zen/middleware/fork_detector"
17
+ require_relative "zen/middleware/context_setter"
18
+ require_relative "zen/middleware/allowed_address_checker"
19
+ require_relative "zen/middleware/attack_wave_protector"
16
20
  require_relative "zen/middleware/request_tracker"
17
- require_relative "zen/middleware/set_context"
18
21
  require_relative "zen/outbound_connection"
19
22
  require_relative "zen/outbound_connection_monitor"
20
23
  require_relative "zen/runtime_settings"
21
24
  require_relative "zen/rate_limiter"
25
+ require_relative "zen/attack_wave"
22
26
  require_relative "zen/scanners"
23
27
 
24
28
  module Aikido
@@ -36,10 +40,8 @@ module Aikido
36
40
  return
37
41
  end
38
42
 
39
- return unless config.protect?
40
-
41
43
  unless load_sources! && load_sinks!
42
- config.logger.warn "Zen could not find any supported libraries or frameworks. Visit https://github.com/AikidoSec/firewall-ruby for more information."
44
+ config.logger.warn("Zen could not find any supported libraries or frameworks. Visit https://github.com/AikidoSec/firewall-ruby for more information.")
43
45
  return
44
46
  end
45
47
 
@@ -78,6 +80,16 @@ module Aikido
78
80
  @runtime_settings = settings
79
81
  end
80
82
 
83
+ # @return [Boolean] whether the Aikido agent is currently blocking requests.
84
+ # Blocking mode is configured at startup and can be controlled through the
85
+ # Aikido dashboard at runtime.
86
+ def self.blocking_mode?
87
+ blocking_mode = runtime_settings.blocking_mode
88
+ return blocking_mode unless blocking_mode.nil?
89
+
90
+ config.blocking_mode
91
+ end
92
+
81
93
  # Gets information about the current system configuration, which is sent to
82
94
  # the server along with any events.
83
95
  def self.system_info
@@ -87,15 +99,9 @@ module Aikido
87
99
  # Manages runtime metrics extracted from your app, which are uploaded to the
88
100
  # Aikido servers if configured to do so.
89
101
  def self.collector
90
- check_and_handle_fork
91
102
  @collector ||= Collector.new
92
103
  end
93
104
 
94
- def self.detached_agent
95
- check_and_handle_fork
96
- @detached_agent ||= DetachedAgent::Agent.new
97
- end
98
-
99
105
  # Gets the current context object that holds all information about the
100
106
  # current request.
101
107
  #
@@ -121,6 +127,18 @@ module Aikido
121
127
  collector.track_request
122
128
  end
123
129
 
130
+ # Track statistics about an attack wave the app is handling.
131
+ #
132
+ # @param attack_wave [Aikido::Zen::Events::AttackWave]
133
+ # @return [void]
134
+ def self.track_attack_wave(attack_wave)
135
+ collector.track_attack_wave(being_blocked: false)
136
+ end
137
+
138
+ # Track statistics about a route that the app has discovered.
139
+ #
140
+ # @param request [Aikido::Zen::Request]
141
+ # @return [void]
124
142
  def self.track_discovered_route(request)
125
143
  collector.track_route(request)
126
144
  end
@@ -165,12 +183,22 @@ module Aikido
165
183
  end
166
184
  end
167
185
 
186
+ # Align with other Zen implementations, while keeping internal consistency.
187
+ class << self
188
+ alias_method :set_user, :track_user
189
+ end
190
+
168
191
  # Marks that the Zen middleware was installed properly
169
192
  # @return void
170
193
  def self.middleware_installed!
171
194
  collector.middleware_installed!
172
195
  end
173
196
 
197
+ # @return [Aikido::Zen::AttackWave::Detector] the attack wave detector.
198
+ def self.attack_wave_detector
199
+ @attack_wave_detector ||= AttackWave::Detector.new
200
+ end
201
+
174
202
  # @!visibility private
175
203
  # Load all sources.
176
204
  #
@@ -208,8 +236,12 @@ module Aikido
208
236
  @agent ||= Agent.start
209
237
  end
210
238
 
239
+ def self.detached_agent
240
+ @detached_agent ||= DetachedAgent::Agent.new
241
+ end
242
+
211
243
  def self.detached_agent_server
212
- @detached_agent_server ||= DetachedAgent::Server.start!
244
+ @detached_agent_server ||= DetachedAgent::Server.start
213
245
  end
214
246
 
215
247
  class << self
@@ -218,24 +250,54 @@ module Aikido
218
250
  LOCK = Mutex.new
219
251
 
220
252
  def start!
253
+ return unless start?
254
+
221
255
  @pid = Process.pid
256
+
222
257
  LOCK.synchronize do
223
258
  agent
224
259
  detached_agent_server
225
260
  end
226
261
  end
227
262
 
263
+ def start?
264
+ !config.api_token.nil? ||
265
+ config.blocking_mode? ||
266
+ config.debugging?
267
+ end
268
+
228
269
  def check_and_handle_fork
229
- if has_forked
230
- @detached_agent&.handle_fork
231
- end
270
+ handle_fork if forked?
232
271
  end
233
272
 
234
- def has_forked
273
+ def forked?
235
274
  pid_changed = Process.pid != @pid
236
275
  @pid = Process.pid
237
276
  pid_changed
238
277
  end
278
+
279
+ def handle_fork
280
+ @detached_agent&.handle_fork
281
+ end
282
+ end
283
+
284
+ # @!visibility private
285
+ # Returns the stack trace trimmed to where execution last entered Zen.
286
+ #
287
+ # @return [String]
288
+ def self.clean_stack_trace
289
+ stack_trace = caller_locations
290
+
291
+ spec = Gem.loaded_specs["aikido-zen"]
292
+
293
+ # Only trim stack frames from .../lib/aikido/zen/ in the aikido-zen gem,
294
+ # so calls in sample apps are preserved.
295
+ lib_path_start = File.expand_path(File.join(spec.full_gem_path, "lib", "aikido", "zen")) + File::SEPARATOR
296
+
297
+ index = stack_trace.index { |frame| !File.expand_path(frame.path).start_with?(lib_path_start) }
298
+ stack_trace = stack_trace[index..] if index
299
+
300
+ stack_trace.map(&:to_s).join("\n")
239
301
  end
240
302
  end
241
303
  end
data/tasklib/bench.rake CHANGED
@@ -87,7 +87,7 @@ Pathname.glob("sample_apps/*").select(&:directory?).each do |dir|
87
87
  end
88
88
 
89
89
  task :boot_unprotected_app do
90
- boot_server(dir, port: PORT_UNPROTECTED, env: {"AIKIDO_DISABLED" => "true"})
90
+ boot_server(dir, port: PORT_UNPROTECTED, env: {"AIKIDO_DISABLE" => "true"})
91
91
  end
92
92
  end
93
93
  end
data/tasklib/libzen.rake CHANGED
@@ -76,6 +76,7 @@ LIBZENS = [
76
76
  LibZen.new("arm64-darwin.dylib", "libzen_internals_aarch64-apple-darwin.dylib"),
77
77
  LibZen.new("arm64-linux.so", "libzen_internals_aarch64-unknown-linux-gnu.so"),
78
78
  LibZen.new("arm64-linux-musl.so", "libzen_internals_aarch64-unknown-linux-musl.so"),
79
+ LibZen.new("aarch64-linux.so", "libzen_internals_aarch64-unknown-linux-gnu.so"),
79
80
  LibZen.new("x86_64-darwin.dylib", "libzen_internals_x86_64-apple-darwin.dylib"),
80
81
  LibZen.new("x86_64-linux.so", "libzen_internals_x86_64-unknown-linux-gnu.so"),
81
82
  LibZen.new("x86_64-linux-musl.so", "libzen_internals_x86_64-unknown-linux-musl.so"),
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.1.beta.4
4
+ version: 1.0.2
5
5
  platform: arm64-linux-musl
6
6
  authors:
7
7
  - Aikido Security
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-08-11 00:00:00.000000000 Z
11
+ date: 2025-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -71,10 +71,13 @@ 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
78
+ - docs/proxy.md
77
79
  - docs/rails.md
80
+ - docs/troubleshooting.md
78
81
  - lib/aikido-zen.rb
79
82
  - lib/aikido/zen.rb
80
83
  - lib/aikido/zen/actor.rb
@@ -82,9 +85,13 @@ files:
82
85
  - lib/aikido/zen/agent/heartbeats_manager.rb
83
86
  - lib/aikido/zen/api_client.rb
84
87
  - lib/aikido/zen/attack.rb
88
+ - lib/aikido/zen/attack_wave.rb
89
+ - lib/aikido/zen/attack_wave/helpers.rb
85
90
  - lib/aikido/zen/background_worker.rb
91
+ - lib/aikido/zen/cache.rb
86
92
  - lib/aikido/zen/capped_collections.rb
87
93
  - lib/aikido/zen/collector.rb
94
+ - lib/aikido/zen/collector/event.rb
88
95
  - lib/aikido/zen/collector/hosts.rb
89
96
  - lib/aikido/zen/collector/routes.rb
90
97
  - lib/aikido/zen/collector/sink_stats.rb
@@ -100,13 +107,16 @@ files:
100
107
  - lib/aikido/zen/detached_agent/server.rb
101
108
  - lib/aikido/zen/errors.rb
102
109
  - lib/aikido/zen/event.rb
110
+ - lib/aikido/zen/helpers.rb
103
111
  - lib/aikido/zen/internals.rb
104
- - lib/aikido/zen/libzen-v0.1.39-arm64-linux-musl.so
105
- - lib/aikido/zen/middleware/check_allowed_addresses.rb
112
+ - lib/aikido/zen/libzen-v0.1.48-arm64-linux-musl.so
113
+ - lib/aikido/zen/middleware/allowed_address_checker.rb
114
+ - lib/aikido/zen/middleware/attack_wave_protector.rb
115
+ - lib/aikido/zen/middleware/context_setter.rb
116
+ - lib/aikido/zen/middleware/fork_detector.rb
106
117
  - lib/aikido/zen/middleware/middleware.rb
107
118
  - lib/aikido/zen/middleware/rack_throttler.rb
108
119
  - lib/aikido/zen/middleware/request_tracker.rb
109
- - lib/aikido/zen/middleware/set_context.rb
110
120
  - lib/aikido/zen/outbound_connection.rb
111
121
  - lib/aikido/zen/outbound_connection_monitor.rb
112
122
  - lib/aikido/zen/package.rb