aikido-zen 0.1.1-arm64-linux → 1.0.0.pre.beta.1-arm64-linux
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 +7 -0
- data/CHANGELOG.md +4 -0
- data/README.md +11 -2
- data/benchmarks/README.md +8 -12
- data/benchmarks/rails7.1_sql_injection.js +30 -34
- data/docs/banner.svg +128 -129
- data/docs/config.md +8 -6
- data/docs/rails.md +1 -1
- data/lib/aikido/zen/agent.rb +13 -9
- data/lib/aikido/zen/api_client.rb +17 -7
- data/lib/aikido/zen/attack.rb +105 -36
- data/lib/aikido/zen/background_worker.rb +52 -0
- data/lib/aikido/zen/collector/routes.rb +2 -0
- data/lib/aikido/zen/collector.rb +31 -4
- data/lib/aikido/zen/config.rb +55 -20
- data/lib/aikido/zen/detached_agent/agent.rb +78 -0
- data/lib/aikido/zen/detached_agent/front_object.rb +37 -0
- data/lib/aikido/zen/detached_agent/server.rb +41 -0
- data/lib/aikido/zen/detached_agent.rb +2 -0
- data/lib/aikido/zen/errors.rb +18 -1
- data/lib/aikido/zen/event.rb +4 -2
- data/lib/aikido/zen/libzen-v0.1.37.aarch64.so +0 -0
- data/lib/aikido/zen/middleware/check_allowed_addresses.rb +2 -14
- data/lib/aikido/zen/middleware/middleware.rb +11 -0
- data/lib/aikido/zen/middleware/{throttler.rb → rack_throttler.rb} +11 -13
- data/lib/aikido/zen/middleware/request_tracker.rb +190 -0
- data/lib/aikido/zen/middleware/set_context.rb +1 -4
- data/lib/aikido/zen/outbound_connection_monitor.rb +4 -0
- data/lib/aikido/zen/payload.rb +2 -0
- data/lib/aikido/zen/rails_engine.rb +12 -0
- data/lib/aikido/zen/rate_limiter/breaker.rb +3 -3
- data/lib/aikido/zen/rate_limiter.rb +7 -12
- data/lib/aikido/zen/request/rails_router.rb +6 -18
- data/lib/aikido/zen/request/schema/auth_schemas.rb +14 -0
- data/lib/aikido/zen/request/schema/builder.rb +0 -2
- data/lib/aikido/zen/request/schema/definition.rb +0 -5
- data/lib/aikido/zen/request/schema.rb +18 -3
- data/lib/aikido/zen/runtime_settings.rb +2 -2
- data/lib/aikido/zen/scanners/path_traversal/helpers.rb +65 -0
- data/lib/aikido/zen/scanners/path_traversal_scanner.rb +63 -0
- data/lib/aikido/zen/scanners/shell_injection/helpers.rb +159 -0
- data/lib/aikido/zen/scanners/shell_injection_scanner.rb +64 -0
- data/lib/aikido/zen/scanners/sql_injection_scanner.rb +4 -6
- data/lib/aikido/zen/scanners/ssrf/private_ip_checker.rb +33 -21
- data/lib/aikido/zen/scanners/ssrf_scanner.rb +15 -7
- data/lib/aikido/zen/scanners/stored_ssrf_scanner.rb +6 -0
- data/lib/aikido/zen/scanners.rb +2 -0
- data/lib/aikido/zen/sink.rb +6 -1
- data/lib/aikido/zen/sinks/action_controller.rb +34 -15
- data/lib/aikido/zen/sinks/file.rb +120 -0
- data/lib/aikido/zen/sinks/kernel.rb +73 -0
- data/lib/aikido/zen/sinks/socket.rb +13 -0
- data/lib/aikido/zen/sinks.rb +8 -0
- data/lib/aikido/zen/system_info.rb +1 -1
- data/lib/aikido/zen/version.rb +2 -2
- data/lib/aikido/zen/worker.rb +5 -0
- data/lib/aikido/zen.rb +54 -8
- data/tasklib/bench.rake +31 -7
- data/tasklib/wrk.rb +88 -0
- metadata +22 -8
- data/lib/aikido/zen/libzen-v0.1.31.aarch64.so +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2ec39a099fb18356244ef6c4634f1a03190a486d08b89d2e455badd06d4f5a2
|
4
|
+
data.tar.gz: 65950e78805aec6fe99cd38957748f989bcad7c90462ad1ee41648290ad6d5f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 836a0bca75d8e2d0dda23b8820eedce546274207e22f9603d1a49b749f72c17d56df5878f6a7d627b35b2d0c49e9e1449dc79ff346a843000087871e4869a9b2
|
7
|
+
data.tar.gz: 0d603bb1618c423e7c0ac47807d6ff442aa54a2e094d12ca4936f87e004fab05995e41d69f706555188804b8cc2ec27276b87364e1654f5b33b468c2637367e7
|
data/.simplecov
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
# SimpleCov version, and it doesn't really give us any benefit to run coverage
|
5
5
|
# in separate ruby versions since we don't branch on ruby version in the code.
|
6
6
|
return if RUBY_VERSION < "3.0"
|
7
|
+
return if ENV["DISABLE_COVERAGE"] == "true"
|
7
8
|
|
8
9
|
SimpleCov.start do
|
9
10
|
# Make sure SimpleCov waits until after the tests
|
@@ -14,6 +15,12 @@ SimpleCov.start do
|
|
14
15
|
minimum_coverage line: 95, branch: 85
|
15
16
|
|
16
17
|
add_filter "/test/"
|
18
|
+
|
19
|
+
# WebMock excludes EM-HTTP-Request on Ruby 3.4:
|
20
|
+
# https://github.com/c960657/webmock/commit/34d16285dbcc574c90b273a89f16cb5fb9f4222a
|
21
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.4.0") && Gem.loaded_specs["em-http-request"].version <= Gem::Version.new("1.1.7")
|
22
|
+
add_filter "lib/aikido/zen/sinks/em_http.rb"
|
23
|
+
end
|
17
24
|
end
|
18
25
|
|
19
26
|
# vim: ft=ruby
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|

|
2
2
|
|
3
|
+
[](https://badge.fury.io/rb/aikido-zen)
|
4
|
+
[](http://makeapullrequest.com)
|
5
|
+
[](https://github.com/AikidoSec/firewall-ruby/actions/workflows/main.yml)
|
6
|
+
[](https://github.com/AikidoSec/firewall-ruby/actions/workflows/release.yml)
|
7
|
+
|
3
8
|
# Zen, in-app firewall for Ruby | by Aikido
|
4
9
|
|
5
10
|
Zen, your in-app firewall for peace of mind—at runtime.
|
@@ -13,8 +18,8 @@ Rails application, for simple installation and zero maintenance.
|
|
13
18
|
|
14
19
|
* 🛡️ [SQL injection attacks](https://www.aikido.dev/blog/the-state-of-sql-injections)
|
15
20
|
* 🛡️ [Server-side request forgery (SSRF)](https://github.com/AikidoSec/firewall-node/blob/main/docs/ssrf.md)
|
16
|
-
* 🛡️ [Command injection attacks](https://
|
17
|
-
* 🛡️ [Path traversal attacks](https://
|
21
|
+
* 🛡️ [Command injection attacks](https://www.aikido.dev/blog/command-injection-in-2024-unpacked) (coming soon)
|
22
|
+
* 🛡️ [Path traversal attacks](https://www.aikido.dev/blog/path-traversal-in-2024-the-year-unpacked) (coming soon)
|
18
23
|
* 🛡️ [NoSQL injection attacks](https://www.aikido.dev/blog/web-application-security-vulnerabilities) (coming soon)
|
19
24
|
|
20
25
|
Zen operates autonomously on the same server as your Rails app to:
|
@@ -81,6 +86,10 @@ To block requests, set the `AIKIDO_BLOCK` environment variable to `true`.
|
|
81
86
|
See [Reporting to Aikido](#reporting-to-your-aikido-security-dashboard) to learn
|
82
87
|
how to send events to Aikido.
|
83
88
|
|
89
|
+
## Additional configuration
|
90
|
+
|
91
|
+
[Configure Zen using environment variables for authentication, mode settings, debugging, and more.](https://help.aikido.dev/doc/configuration-via-env-vars/docrSItUkeR9)
|
92
|
+
|
84
93
|
## Reporting to your Aikido Security dashboard
|
85
94
|
|
86
95
|
> Aikido is your no nonsense application security platform. One central system
|
data/benchmarks/README.md
CHANGED
@@ -1,27 +1,23 @@
|
|
1
1
|
# Benchmarking Zen for Ruby
|
2
2
|
|
3
|
-
This directory contains the benchmarking scripts that we use to ensure adding
|
4
|
-
Zen to your application does not impact performance significantly.
|
5
3
|
|
6
|
-
We use [Grafana K6](https://k6.io) for these.
|
7
|
-
include in this repo under [sample_apps](../sample_apps), you should find
|
8
|
-
a script here that runs certain benchmarks against that app.
|
4
|
+
We use [WRK](https://github.com/wg/wrk) & [Grafana K6](https://k6.io) for these.
|
9
5
|
|
10
|
-
|
6
|
+
WRK benchmarks are only requesting a URL (`/benchmark`). In case you want to add more
|
7
|
+
of those test, you have to code them in the file `tasklib/bench.rake`.
|
11
8
|
|
12
|
-
|
13
|
-
|
14
|
-
```
|
9
|
+
K6 tests are defined in `benchmarks` folder. They are a javascript file, with calls
|
10
|
+
to different endpoints.
|
15
11
|
|
16
12
|
In order to run a benchmarks against a single application, run the following
|
17
13
|
from the root of the project:
|
18
14
|
|
19
15
|
```
|
20
|
-
$ bundle exec rake bench:{app}:
|
16
|
+
$ BUNDLE_GEMFILE=./sample_apps/{app}/Gemfile bundle exec rake bench:{app}:(k6|wrk)_run
|
21
17
|
```
|
22
18
|
|
23
|
-
For example, for the `rails7.
|
19
|
+
For example, for the WRK of `rails7.1_benchmark` application:
|
24
20
|
|
25
21
|
```
|
26
|
-
$ bundle exec rake bench:rails7.
|
22
|
+
$ BUNDLE_GEMFILE=./sample_apps/rails7.1_benchmark/Gemfile bundle exec rake bench:rails7.1_benchmark:wrk_run
|
27
23
|
```
|
@@ -1,8 +1,5 @@
|
|
1
1
|
import http from 'k6/http';
|
2
|
-
import {
|
3
|
-
import { check, sleep, fail } from 'k6';
|
4
|
-
import exec from 'k6/execution';
|
5
|
-
import { Trend } from 'k6/metrics';
|
2
|
+
import {Trend} from 'k6/metrics';
|
6
3
|
|
7
4
|
const HTTP = {
|
8
5
|
withZen: {
|
@@ -16,59 +13,58 @@ const HTTP = {
|
|
16
13
|
}
|
17
14
|
|
18
15
|
function test(name, fn) {
|
19
|
-
const duration = tests[name].duration;
|
20
|
-
const overhead = tests[name].overhead;
|
21
|
-
|
22
16
|
const withZen = fn(HTTP.withZen);
|
23
17
|
const withoutZen = fn(HTTP.withoutZen);
|
18
|
+
const timeWithZen = withZen.timings.duration;
|
19
|
+
const timeWithoutZen = withoutZen.timings.duration;
|
24
20
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
duration.add(timeWithZen - timeWithoutZen);
|
21
|
+
tests[name].delta.add(timeWithZen - timeWithoutZen);
|
22
|
+
tests[name].overhead.add(100 * (timeWithZen - timeWithoutZen) / timeWithoutZen)
|
29
23
|
|
30
|
-
|
31
|
-
|
24
|
+
tests[name].with_zen.add(timeWithZen);
|
25
|
+
tests[name].without_zen.add(timeWithoutZen);
|
32
26
|
}
|
33
27
|
|
34
|
-
|
35
|
-
|
36
|
-
}
|
28
|
+
function buildTestTrends(prefix) {
|
29
|
+
return {
|
30
|
+
delta: new Trend(`${prefix}_delta`),
|
31
|
+
with_zen: new Trend(`${prefix}_with_zen`),
|
32
|
+
without_zen: new Trend(`${prefix}_without_zen`),
|
33
|
+
overhead: new Trend(`${prefix}_overhead`)
|
34
|
+
};
|
35
|
+
}
|
37
36
|
|
38
37
|
const tests = {
|
39
|
-
test_post_page_with_json_body:
|
40
|
-
|
41
|
-
|
42
|
-
},
|
43
|
-
test_get_page_without_attack: {
|
44
|
-
duration: new Trend("test_get_page_without_attack"),
|
45
|
-
overhead: new Trend("test_overhead_without_attack")
|
46
|
-
},
|
47
|
-
test_get_page_with_sql_injection: {
|
48
|
-
duration: new Trend("test_get_page_with_sql_injection"),
|
49
|
-
overhead: new Trend("test_overhead_with_sql_injection"),
|
50
|
-
}
|
38
|
+
test_post_page_with_json_body: buildTestTrends("test_post_page_with_json_body"),
|
39
|
+
test_get_page_without_attack: buildTestTrends("test_get_page_without_attack"),
|
40
|
+
test_get_page_with_sql_injection: buildTestTrends("test_get_page_with_sql_injection")
|
51
41
|
}
|
52
42
|
export const options = {
|
53
43
|
vus: 1, // Number of virtual users
|
54
44
|
iterations: 200,
|
55
45
|
thresholds: {
|
56
|
-
|
57
|
-
|
58
|
-
|
46
|
+
http_req_failed: ['rate==0'], // we are marking the attacks as expected, so we should have no errors
|
47
|
+
test_post_page_with_json_body_delta: ["med<10"],
|
48
|
+
test_get_page_without_attack_delta: ["med<10"],
|
49
|
+
test_get_page_with_sql_injection_delta: ["med<10"],
|
59
50
|
}
|
60
51
|
};
|
61
52
|
|
62
|
-
const expectAttack = http.expectedStatuses(500);
|
53
|
+
const expectAttack = http.expectedStatuses(200, 500);
|
63
54
|
|
64
55
|
export default function () {
|
65
56
|
test("test_post_page_with_json_body",
|
66
57
|
(http) => http.post("/cats", JSON.stringify({cat: {name: "Féline Dion"}}), {
|
67
|
-
headers: {
|
58
|
+
headers: {
|
59
|
+
"Content-Type": "application/json",
|
60
|
+
"Accept": "application/json"
|
61
|
+
}
|
68
62
|
})
|
69
63
|
)
|
64
|
+
|
70
65
|
test("test_get_page_without_attack", (http) => http.get("/cats"))
|
66
|
+
|
71
67
|
test("test_get_page_with_sql_injection", (http) =>
|
72
|
-
http.get("/cats/1'%20OR%20''='", {responseCallback: expectAttack})
|
68
|
+
http.get("/cats/1'%20OR%20''='", { responseCallback: expectAttack })
|
73
69
|
)
|
74
70
|
}
|