aikido-zen 1.0.2.beta.1-x86_64-darwin → 1.0.2.beta.5-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 +4 -4
- data/docs/proxy.md +10 -0
- data/docs/rails.md +1 -1
- data/lib/aikido/zen/attack.rb +12 -4
- data/lib/aikido/zen/config.rb +13 -2
- data/lib/aikido/zen/payload.rb +1 -1
- data/lib/aikido/zen/request.rb +21 -2
- data/lib/aikido/zen/scanners/stored_ssrf_scanner.rb +3 -1
- data/lib/aikido/zen/version.rb +1 -1
- data/tasklib/libzen.rake +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ccfabb53e6358207908bf6989567f72189e2f64a330bf057d3cff2d1b766abf
|
4
|
+
data.tar.gz: b9ad9706eb476db63a0935ac51eeb0b123919a4b078ef41b8d295d1e12607dd6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c9d5827a80d43f2fbfef0d23d87d55667b59ced61da74b1d7d94f68d1f064128254ff5819142e5f0e77854e5dc03222b1dc43db307e9d6635d0b51e0277d4a6
|
7
|
+
data.tar.gz: 7fd82ba385dbe8a579df66ea095c1d9f3e73ad264c57020c934efd092d3e86e9cb87cdeb21808d69e81d6ac3a3da7bce5df02fd64605d629741fceb697e74083
|
data/docs/proxy.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# Proxy settings
|
2
|
+
|
3
|
+
We'll automatically use the `HTTP_X_FORWARDED_FOR` header to determine the client's IP address when behind a trusted proxy.
|
4
|
+
|
5
|
+
If you need to use a different header to determine the client's IP address, you can set the `AIKIDO_CLIENT_IP_HEADER` environment variable to the name of that header. This will override the default `HTTP_X_FORWARDED_FOR` header.
|
6
|
+
|
7
|
+
```bash
|
8
|
+
# For Fly.io Platform
|
9
|
+
AIKIDO_CLIENT_IP_HEADER=HTTP_FLY_CLIENT_IP bin/rails server
|
10
|
+
```
|
data/docs/rails.md
CHANGED
@@ -66,7 +66,7 @@ Rails.application.config.zen.api_timeouts = 20
|
|
66
66
|
You can access the configuration object both as `Aikido::Zen.config` or
|
67
67
|
`Rails.configuration.zen`.
|
68
68
|
|
69
|
-
See our [configuration guide](
|
69
|
+
See our [configuration guide](./config.md) for more details.
|
70
70
|
|
71
71
|
## Using Rails encrypted credentials
|
72
72
|
|
data/lib/aikido/zen/attack.rb
CHANGED
@@ -67,7 +67,9 @@ module Aikido::Zen
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def metadata
|
70
|
-
{
|
70
|
+
{
|
71
|
+
filename: filepath
|
72
|
+
}
|
71
73
|
end
|
72
74
|
|
73
75
|
def humanized_name
|
@@ -133,7 +135,10 @@ module Aikido::Zen
|
|
133
135
|
end
|
134
136
|
|
135
137
|
def metadata
|
136
|
-
{
|
138
|
+
{
|
139
|
+
sql: @query,
|
140
|
+
dialect: @dialect
|
141
|
+
}
|
137
142
|
end
|
138
143
|
|
139
144
|
def exception(*)
|
@@ -165,7 +170,7 @@ module Aikido::Zen
|
|
165
170
|
|
166
171
|
def metadata
|
167
172
|
{
|
168
|
-
|
173
|
+
hostname: @request.uri.hostname,
|
169
174
|
port: @request.uri.port
|
170
175
|
}
|
171
176
|
end
|
@@ -200,7 +205,10 @@ module Aikido::Zen
|
|
200
205
|
end
|
201
206
|
|
202
207
|
def metadata
|
203
|
-
{
|
208
|
+
{
|
209
|
+
hostname: @hostname,
|
210
|
+
resolvedIP: @address
|
211
|
+
}
|
204
212
|
end
|
205
213
|
end
|
206
214
|
end
|
data/lib/aikido/zen/config.rb
CHANGED
@@ -61,7 +61,7 @@ module Aikido::Zen
|
|
61
61
|
# @return [Logger]
|
62
62
|
attr_reader :logger
|
63
63
|
|
64
|
-
# @return [
|
64
|
+
# @return [String] Path of the socket where the detached agent will listen.
|
65
65
|
# By default, is stored under the root application path with file name
|
66
66
|
# `aikido-detached-agent.sock`
|
67
67
|
attr_accessor :detached_agent_socket_path
|
@@ -70,6 +70,9 @@ module Aikido::Zen
|
|
70
70
|
attr_accessor :debugging
|
71
71
|
alias_method :debugging?, :debugging
|
72
72
|
|
73
|
+
# @return [String] environment specific HTTP header providing the client IP.
|
74
|
+
attr_accessor :client_ip_header
|
75
|
+
|
73
76
|
# @return [Integer] maximum number of timing measurements to keep in memory
|
74
77
|
# before compressing them.
|
75
78
|
attr_accessor :max_performance_samples
|
@@ -146,6 +149,12 @@ module Aikido::Zen
|
|
146
149
|
# the server returns a 429 response.
|
147
150
|
attr_accessor :server_rate_limit_deadline
|
148
151
|
|
152
|
+
# @return [Boolean] whether Aikido Zen should scan for stored SSSRF attacks.
|
153
|
+
# Defaults to true. Can be set through AIKIDO_FEATURE_STORED_SSRF
|
154
|
+
# environment variable.
|
155
|
+
attr_accessor :stored_ssrf
|
156
|
+
alias_method :stored_ssrf?, :stored_ssrf
|
157
|
+
|
149
158
|
# @return [Array<String>] when checking for stored SSRF attacks, we want to
|
150
159
|
# allow known hosts that should be able to resolve to the IMDS service.
|
151
160
|
attr_accessor :imds_allowed_hosts
|
@@ -163,8 +172,9 @@ module Aikido::Zen
|
|
163
172
|
self.json_decoder = DEFAULT_JSON_DECODER
|
164
173
|
self.debugging = read_boolean_from_env(ENV.fetch("AIKIDO_DEBUG", false))
|
165
174
|
self.logger = Logger.new($stdout, progname: "aikido", level: debugging ? Logger::DEBUG : Logger::INFO)
|
166
|
-
self.max_performance_samples = 5000
|
167
175
|
self.detached_agent_socket_path = ENV.fetch("AIKIDO_DETACHED_AGENT_SOCKET_PATH", DEFAULT_DETACHED_AGENT_SOCKET_PATH)
|
176
|
+
self.client_ip_header = ENV.fetch("AIKIDO_CLIENT_IP_HEADER", nil)
|
177
|
+
self.max_performance_samples = 5000
|
168
178
|
self.max_compressed_stats = 100
|
169
179
|
self.max_outbound_connections = 200
|
170
180
|
self.max_users_tracked = 1000
|
@@ -179,6 +189,7 @@ module Aikido::Zen
|
|
179
189
|
self.api_schema_max_samples = Integer(ENV.fetch("AIKIDO_MAX_API_DISCOVERY_SAMPLES", 10))
|
180
190
|
self.api_schema_collection_max_depth = 20
|
181
191
|
self.api_schema_collection_max_properties = 20
|
192
|
+
self.stored_ssrf = read_boolean_from_env(ENV.fetch("AIKIDO_FEATURE_STORED_SSRF", true))
|
182
193
|
self.imds_allowed_hosts = ["metadata.google.internal", "metadata.goog"]
|
183
194
|
end
|
184
195
|
|
data/lib/aikido/zen/payload.rb
CHANGED
data/lib/aikido/zen/request.rb
CHANGED
@@ -17,8 +17,9 @@ module Aikido::Zen
|
|
17
17
|
# @see Aikido::Zen.track_user
|
18
18
|
attr_accessor :actor
|
19
19
|
|
20
|
-
def initialize(delegate, framework:, router:)
|
20
|
+
def initialize(delegate, config = Aikido::Zen.config, framework:, router:)
|
21
21
|
super(delegate)
|
22
|
+
@config = config
|
22
23
|
@framework = framework
|
23
24
|
@router = router
|
24
25
|
@body_read = false
|
@@ -40,6 +41,24 @@ module Aikido::Zen
|
|
40
41
|
@schema ||= Aikido::Zen::Request::Schema.build
|
41
42
|
end
|
42
43
|
|
44
|
+
# @api private
|
45
|
+
#
|
46
|
+
# @return [String] the IP address of the client making the request.
|
47
|
+
def client_ip
|
48
|
+
return @client_ip if @client_ip
|
49
|
+
|
50
|
+
if @config.client_ip_header
|
51
|
+
value = env[@config.client_ip_header]
|
52
|
+
if Resolv::AddressRegex.match?(value)
|
53
|
+
@client_ip = value
|
54
|
+
else
|
55
|
+
@config.logger.warn("Invalid IP address in custom client IP header `#{@config.client_ip_header}`: `#{value}`")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
@client_ip ||= respond_to?(:remote_ip) ? remote_ip : ip
|
60
|
+
end
|
61
|
+
|
43
62
|
# Map the CGI-style env Hash into "pretty-looking" headers, preserving the
|
44
63
|
# values as-is. For example, HTTP_ACCEPT turns into "Accept", CONTENT_TYPE
|
45
64
|
# turns into "Content-Type", and HTTP_X_FORWARDED_FOR turns into
|
@@ -87,7 +106,7 @@ module Aikido::Zen
|
|
87
106
|
{
|
88
107
|
method: request_method.downcase,
|
89
108
|
url: url,
|
90
|
-
ipAddress:
|
109
|
+
ipAddress: client_ip,
|
91
110
|
userAgent: user_agent,
|
92
111
|
headers: normalized_headers.reject { |_, val| val.to_s.empty? },
|
93
112
|
body: truncated_body,
|
@@ -33,7 +33,9 @@ module Aikido::Zen
|
|
33
33
|
# @return [String, nil] either the offending address, or +nil+ if no
|
34
34
|
# address is deemed dangerous.
|
35
35
|
def attack?
|
36
|
-
return
|
36
|
+
return unless @config.stored_ssrf? # Feature flag
|
37
|
+
|
38
|
+
return if @config.imds_allowed_hosts.include?(@hostname)
|
37
39
|
|
38
40
|
@addresses.find do |candidate|
|
39
41
|
DANGEROUS_ADDRESSES.any? { |address| address === candidate }
|
data/lib/aikido/zen/version.rb
CHANGED
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.2.beta.
|
4
|
+
version: 1.0.2.beta.5
|
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-
|
11
|
+
date: 2025-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -74,6 +74,7 @@ files:
|
|
74
74
|
- benchmarks/rails7.1_sql_injection.js
|
75
75
|
- docs/banner.svg
|
76
76
|
- docs/config.md
|
77
|
+
- docs/proxy.md
|
77
78
|
- docs/rails.md
|
78
79
|
- lib/aikido-zen.rb
|
79
80
|
- lib/aikido/zen.rb
|