aikido-zen 0.1.1 → 0.2.0
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 +1 -0
- data/CHANGELOG.md +4 -0
- data/README.md +11 -2
- 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 +2 -2
- data/lib/aikido/zen/agent.rb +3 -1
- data/lib/aikido/zen/api_client.rb +3 -3
- data/lib/aikido/zen/attack.rb +105 -36
- data/lib/aikido/zen/collector/routes.rb +2 -0
- data/lib/aikido/zen/collector.rb +19 -3
- data/lib/aikido/zen/config.rb +44 -20
- data/lib/aikido/zen/errors.rb +10 -1
- data/lib/aikido/zen/event.rb +4 -2
- 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} +3 -11
- data/lib/aikido/zen/middleware/request_tracker.rb +190 -0
- data/lib/aikido/zen/middleware/set_context.rb +1 -4
- data/lib/aikido/zen/payload.rb +2 -0
- data/lib/aikido/zen/rails_engine.rb +8 -0
- data/lib/aikido/zen/rate_limiter.rb +1 -1
- 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 +0 -3
- data/lib/aikido/zen/scanners/path_traversal/helpers.rb +65 -0
- data/lib/aikido/zen/scanners/path_traversal_scanner.rb +61 -0
- data/lib/aikido/zen/scanners/shell_injection/helpers.rb +159 -0
- data/lib/aikido/zen/scanners/shell_injection_scanner.rb +62 -0
- data/lib/aikido/zen/scanners/sql_injection_scanner.rb +0 -4
- data/lib/aikido/zen/scanners/ssrf_scanner.rb +9 -6
- data/lib/aikido/zen/scanners.rb +2 -0
- data/lib/aikido/zen/sinks/action_controller.rb +26 -12
- data/lib/aikido/zen/sinks/file.rb +120 -0
- data/lib/aikido/zen/sinks/kernel.rb +73 -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.rb +14 -1
- data/tasklib/bench.rake +3 -2
- metadata +15 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2d5b546f3efb35bf92037dadca096f182caa285fe03edd5192af3c967d1eb81
|
4
|
+
data.tar.gz: a745a9556f5d89a2ad3c7cb85aaa5a9d2f615d6c376c14fd99e7955f91a398fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce63a42135ebabcdf81fa288fad9e21c8656b72829fdf1ce50be5085f5ab7020136e84a5ba043e3cf75f523abef02a913d6faa764dd57479a3988e347e03ab9b
|
7
|
+
data.tar.gz: 84b27a54558f890a1f34e217f1d16e6945345686a4e14ce03fa9f2965a30374984f55623ef45b713f3f5d8a3191a7cc6984294995ef946210d0b0e000aaa88bd
|
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
|
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
|
@@ -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
|
}
|