aikido-zen 1.0.1.beta.2-x86_64-darwin → 1.0.1.beta.3-x86_64-darwin

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: 28a25599141a8f5d53bfb25e15b5bdbf0ed1e80498f1ea44b60e0fcf8ef0b89f
4
- data.tar.gz: be0a37db763705328b70dac893df44c37a80e10269c221b03362f53e0cd46aa4
3
+ metadata.gz: 944b8e900edf1fe4635f683ce9d4de91b19f5aeeefe37131e0b0db633f923ecb
4
+ data.tar.gz: 0fd37dad8ff09c7ab8ece11c7d446107d750c29d9595b9b91256f40340a2ceea
5
5
  SHA512:
6
- metadata.gz: 585f2cb09ffe051bbbe750827b50d4df5c25cdcd0970cfae351e672610eda214fccc4903eeb99ea56468f5d2ee2a7fb7511a83f0229059f7a357c4a9c9a2b08a
7
- data.tar.gz: 05d8b84f0bd367e13ba8b14eccd08c39ef5cf7e7942b42b00ccaecea2f5590df635ac4afb8110d6b93ad15f07d38a91c0ee3785995494947f74ac88c2d4ec9c4
6
+ metadata.gz: 1f9ca82665fdbeb178495f5e536e5363fca574ee664dfcf4c9afeed8b5622b93c5ce496c61b1e047696ebfb2b9c74198e44820dd502dbafb96af1bacd0082454
7
+ data.tar.gz: 3114a88e70d1bd6e2c25b68ebfc1c5f0aabbfb481d8c317144b97bbb6e3313fa95429443353d95cc5433a8ffdf1fd2822013946d7e557e482bb38b7fe10c2e86
data/README.md CHANGED
@@ -61,7 +61,7 @@ See list above for supported database drivers.
61
61
  * ✅ [`curb`](https://github.com/taf2/curb) 0.x (0.2.3+), 1.x
62
62
  * ✅ [`patron`](https://github.com/toland/patron) 0.x (0.6.4+)
63
63
  * ✅ [`typhoeus`](https://github.com/typhoeus/typhoeus) 0.x (0.5.0+), 1.x
64
- * ✅ [`async-http`](https://github.com/igrigorik/em-http-request) 0.x (0.70.0+)
64
+ * ✅ [`async-http`](https://github.com/socketry/async-http) 0.x (0.70.0+)
65
65
  * ✅ [`em-http-request`](https://github.com/igrigorik/em-http-request) 1.x
66
66
 
67
67
  ## Installation
@@ -111,7 +111,7 @@ module Aikido::Zen
111
111
  # @raise [Aikido::Zen::NetworkError] if an error occurs trying to make the
112
112
  # request.
113
113
  private def request(request, base_url: @config.api_endpoint)
114
- Net::HTTP.start(base_url.host, base_url.port, http_settings) do |http|
114
+ Net::HTTP.start(base_url.host, base_url.port, http_settings(base_url)) do |http|
115
115
  response = http.request(request)
116
116
 
117
117
  case response
@@ -127,8 +127,11 @@ module Aikido::Zen
127
127
  raise NetworkError.new(request, err)
128
128
  end
129
129
 
130
- private def http_settings
131
- @http_settings ||= {use_ssl: true, max_retries: 2}.merge(@config.api_timeouts)
130
+ private def http_settings(base_url)
131
+ @http_settings ||= {
132
+ use_ssl: base_url.scheme == "https",
133
+ max_retries: 2
134
+ }.merge(@config.api_timeouts)
132
135
  end
133
136
 
134
137
  private def default_headers
@@ -12,7 +12,9 @@ module Aikido::Zen
12
12
 
13
13
  # @!visibility private
14
14
  Context::RAILS_REQUEST_BUILDER = ->(env) do
15
- delegate = ActionDispatch::Request.new(env)
15
+ # Duplicate the Rack environment to prevent unexpected modifications from
16
+ # breaking Rails routing.
17
+ delegate = ActionDispatch::Request.new(env.dup)
16
18
  request = Aikido::Zen::Request.new(
17
19
  delegate, framework: "rails", router: Rails.router
18
20
  )
@@ -7,12 +7,6 @@ module Aikido::Zen
7
7
  module Internals
8
8
  extend FFI::Library
9
9
 
10
- class << self
11
- # @return [String] the name of the extension we're loading, which we can
12
- # use in error messages to identify the architecture.
13
- attr_accessor :libzen_name
14
- end
15
-
16
10
  def self.libzen_names
17
11
  lib_name = "libzen-v#{LIBZEN_VERSION}"
18
12
  lib_ext = FFI::Platform::LIBSUFFIX
@@ -40,17 +34,24 @@ module Aikido::Zen
40
34
  names
41
35
  end
42
36
 
37
+ # @return [String] the name of the extension we're loading, which we can
38
+ # use in error messages.
39
+ def self.libzen_name
40
+ # The most generic platform library name.
41
+ libzen_names.last
42
+ end
43
+
43
44
  # Load the most specific library
44
45
  def self.load_libzen
45
- libzen_names.each do |libzen_name|
46
- libzen_path = File.expand_path(libzen_name, __dir__)
46
+ libzen_names.each do |name|
47
+ path = File.expand_path(name, __dir__)
47
48
  begin
48
- return ffi_lib(libzen_path)
49
+ return ffi_lib(path)
49
50
  rescue LoadError
50
51
  # empty
51
52
  end
52
53
  end
53
- raise LoadError, "Could not load libzen"
54
+ raise LoadError, "Zen could not load its native extension #{libzen_name}"
54
55
  end
55
56
 
56
57
  begin
@@ -68,11 +69,11 @@ module Aikido::Zen
68
69
  # :nocov:
69
70
 
70
71
  # Emit an $stderr warning at startup.
71
- warn "Zen could not load its binary extension #{libzen_name}: #{err}"
72
+ warn "Zen could not load its native extension #{libzen_name}: #{err}"
72
73
 
73
74
  def self.detect_sql_injection(query, *)
74
75
  attempt = format("%p for SQL injection", query)
75
- raise InternalsError.new(attempt, "loading", Internals.libzen_name)
76
+ raise InternalsError.new(attempt, "loading", libzen_name)
76
77
  end
77
78
 
78
79
  # :nocov:
@@ -34,8 +34,8 @@ module Aikido::Zen
34
34
  # Allow the logger to be configured before checking if disabled? so we can
35
35
  # let the user know that the agent is disabled.
36
36
  logger = ::Rails.logger
37
- logger = ActiveSupport::TaggedLogging.new(logger) unless logger.respond_to?(:tagged)
38
- app.config.zen.logger = logger.tagged("aikido")
37
+ logger = logger.tagged("aikido") if logger.respond_to?(:tagged)
38
+ app.config.zen.logger = logger
39
39
 
40
40
  app.config.zen.request_builder = Aikido::Zen::Context::RAILS_REQUEST_BUILDER
41
41
 
@@ -29,6 +29,11 @@ module Aikido::Zen
29
29
  end
30
30
 
31
31
  private def recognize_in_route_set(request, route_set, prefix: nil)
32
+ # ActionDispatch::Journey::Router#recognize modifies the Rack environment.
33
+ # This is correct for Rails routing, but it is not expected to be used in
34
+ # Rack middleware, and using it here can break Rails routing.
35
+ #
36
+ # To avoid this, the Rack environment is duplicated when building request.
32
37
  route_set.router.recognize(request) do |route, _|
33
38
  app = route.app
34
39
  next unless app.matches?(request)
@@ -8,7 +8,7 @@ module Aikido::Zen
8
8
  module Async
9
9
  module HTTP
10
10
  def self.load_sinks!
11
- if Gem.loaded_specs["async-http"]
11
+ if Aikido::Zen.satisfy "async-http", ">= 0.70.0"
12
12
  require "async/http"
13
13
 
14
14
  ::Async::HTTP::Client.prepend(Async::HTTP::ClientExtensions)
@@ -7,7 +7,7 @@ module Aikido::Zen
7
7
  module Sinks
8
8
  module Curl
9
9
  def self.load_sinks!
10
- if Gem.loaded_specs["curb"]
10
+ if Aikido::Zen.satisfy "curb", ">= 0.2.3"
11
11
  require "curb"
12
12
 
13
13
  ::Curl::Easy.prepend(Curl::EasyExtensions)
@@ -8,7 +8,7 @@ module Aikido::Zen
8
8
  module EventMachine
9
9
  module HttpRequest
10
10
  def self.load_sinks!
11
- if Gem.loaded_specs["em-http-request"]
11
+ if Aikido::Zen.satisfy "em-http-request", ">= 1.0"
12
12
  require "em-http-request"
13
13
 
14
14
  ::EventMachine::HttpRequest.use(EventMachine::HttpRequest::Middleware)
@@ -7,7 +7,7 @@ module Aikido::Zen
7
7
  module Sinks
8
8
  module Excon
9
9
  def self.load_sinks!
10
- if Gem.loaded_specs["excon"]
10
+ if Aikido::Zen.satisfy "excon", ">= 0.50.0"
11
11
  require "excon"
12
12
 
13
13
  ::Excon::Connection.prepend(ConnectionExtensions)
@@ -7,7 +7,7 @@ module Aikido::Zen
7
7
  module Sinks
8
8
  module HTTP
9
9
  def self.load_sinks!
10
- if Gem.loaded_specs["http"]
10
+ if Aikido::Zen.satisfy "http", ">= 1.0"
11
11
  require "http"
12
12
 
13
13
  ::HTTP::Client.prepend(ClientExtensions)
@@ -7,7 +7,7 @@ module Aikido::Zen
7
7
  module Sinks
8
8
  module HTTPClient
9
9
  def self.load_sinks!
10
- if Gem.loaded_specs["httpclient"]
10
+ if Aikido::Zen.satisfy "httpclient", ">= 2.0"
11
11
  require "httpclient"
12
12
 
13
13
  ::HTTPClient.prepend(HTTPClient::HTTPClientExtensions)
@@ -7,7 +7,7 @@ module Aikido::Zen
7
7
  module Sinks
8
8
  module HTTPX
9
9
  def self.load_sinks!
10
- if Gem.loaded_specs["httpx"]
10
+ if Aikido::Zen.satisfy "httpx", ">= 1.1.3"
11
11
  require "httpx"
12
12
 
13
13
  ::HTTPX::Session.prepend(HTTPX::SessionExtensions)
@@ -4,7 +4,7 @@ module Aikido::Zen
4
4
  module Sinks
5
5
  module Mysql2
6
6
  def self.load_sinks!
7
- if Gem.loaded_specs["mysql2"]
7
+ if Aikido::Zen.satisfy "mysql2"
8
8
  require "mysql2"
9
9
 
10
10
  ::Mysql2::Client.prepend(ClientExtensions)
@@ -7,7 +7,7 @@ module Aikido::Zen
7
7
  module Sinks
8
8
  module Patron
9
9
  def self.load_sinks!
10
- if Gem.loaded_specs["patron"]
10
+ if Aikido::Zen.satisfy "patron", ">= 0.6.4"
11
11
  require "patron"
12
12
 
13
13
  ::Patron::Session.prepend(SessionExtensions)
@@ -4,7 +4,7 @@ module Aikido::Zen
4
4
  module Sinks
5
5
  module PG
6
6
  def self.load_sinks!
7
- if Gem.loaded_specs["pg"]
7
+ if Aikido::Zen.satisfy "pg", ">= 1.0"
8
8
  require "pg"
9
9
 
10
10
  ::PG::Connection.prepend(PG::ConnectionExtensions)
@@ -4,7 +4,7 @@ module Aikido::Zen
4
4
  module Sinks
5
5
  module SQLite3
6
6
  def self.load_sinks!
7
- if Gem.loaded_specs["sqlite3"]
7
+ if Aikido::Zen.satisfy "sqlite3", ">= 1.0"
8
8
  require "sqlite3"
9
9
 
10
10
  ::SQLite3::Database.prepend(DatabaseExtensions)
@@ -4,7 +4,7 @@ module Aikido::Zen
4
4
  module Sinks
5
5
  module Trilogy
6
6
  def self.load_sinks!
7
- if Gem.loaded_specs["trilogy"]
7
+ if Aikido::Zen.satisfy "trilogy", ">= 2.0"
8
8
  require "trilogy"
9
9
 
10
10
  ::Trilogy.prepend(TrilogyExtensions)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Aikido
4
4
  module Zen
5
- VERSION = "1.0.1.beta.2"
5
+ VERSION = "1.0.1.beta.3"
6
6
 
7
7
  # The version of libzen_internals that we build against.
8
8
  LIBZEN_VERSION = "0.1.39"
data/lib/aikido/zen.rb CHANGED
@@ -38,7 +38,31 @@ module Aikido
38
38
 
39
39
  # IMPORTANT: Any files that load sinks or start the Aikido Agent
40
40
  # should be required here only.
41
- require_relative "zen/rails_engine" if defined?(::Rails)
41
+
42
+ if Aikido::Zen.satisfy "rails", ">= 7.0"
43
+ require_relative "zen/rails_engine"
44
+ end
45
+
46
+ if Aikido::Zen::Sinks.registry.empty?
47
+ warn "Zen could not find any supported libraries or frameworks. Visit https://github.com/AikidoSec/firewall-ruby for more information."
48
+ end
49
+ end
50
+
51
+ # @!visibility private
52
+ # Returns whether the loaded gem specification satisfies the listed requirements.
53
+ #
54
+ # Returns false if the gem specification is not loaded.
55
+ #
56
+ # @param name [String] the gem name
57
+ # @param requirements [Array<String>] a variable number of gem requirement strings
58
+ #
59
+ # @return [Boolean] true if the gem specification is loaded and all gem requirements are satisfied
60
+ def self.satisfy(name, *requirements)
61
+ spec = Gem.loaded_specs[name]
62
+
63
+ return false if spec.nil?
64
+
65
+ Gem::Requirement.new(*requirements).satisfied_by?(spec.version)
42
66
  end
43
67
 
44
68
  # @return [Aikido::Zen::Config] the agent configuration.
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.2
4
+ version: 1.0.1.beta.3
5
5
  platform: x86_64-darwin
6
6
  authors:
7
7
  - Aikido Security
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-07-30 00:00:00.000000000 Z
11
+ date: 2025-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby