aikido-zen 0.1.0.alpha4-x86_64-darwin → 0.1.0-x86_64-darwin
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +136 -23
- data/Rakefile +4 -0
- data/benchmarks/README.md +27 -0
- data/benchmarks/rails7.1_sql_injection.js +74 -0
- data/docs/banner.svg +203 -0
- data/docs/config.md +123 -0
- data/docs/rails.md +70 -0
- data/lib/aikido/zen/actor.rb +1 -1
- data/lib/aikido/zen/agent/heartbeats_manager.rb +66 -0
- data/lib/aikido/zen/agent.rb +98 -112
- data/lib/aikido/zen/collector/hosts.rb +15 -0
- data/lib/aikido/zen/collector/routes.rb +64 -0
- data/lib/aikido/zen/{stats → collector}/sink_stats.rb +1 -1
- data/lib/aikido/zen/collector/stats.rb +111 -0
- data/lib/aikido/zen/{stats → collector}/users.rb +6 -2
- data/lib/aikido/zen/collector.rb +117 -0
- data/lib/aikido/zen/config.rb +17 -11
- data/lib/aikido/zen/context.rb +8 -1
- data/lib/aikido/zen/errors.rb +3 -1
- data/lib/aikido/zen/event.rb +7 -4
- data/lib/aikido/zen/{libzen-v0.1.26.x86_64.dylib → libzen-v0.1.30.x86_64.dylib} +0 -0
- data/lib/aikido/zen/middleware/set_context.rb +4 -1
- data/lib/aikido/zen/rails_engine.rb +27 -18
- data/lib/aikido/zen/request/schema/builder.rb +0 -2
- data/lib/aikido/zen/request.rb +6 -0
- data/lib/aikido/zen/runtime_settings.rb +6 -11
- data/lib/aikido/zen/sinks/action_controller.rb +64 -0
- data/lib/aikido/zen/sinks.rb +1 -0
- data/lib/aikido/zen/version.rb +2 -2
- data/lib/aikido/zen/worker.rb +82 -0
- data/lib/aikido/zen.rb +55 -50
- data/tasklib/bench.rake +70 -0
- metadata +19 -9
- data/CODE_OF_CONDUCT.md +0 -132
- data/lib/aikido/zen/stats/routes.rb +0 -53
- data/lib/aikido/zen/stats.rb +0 -171
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5950e63b5d2cf450319180656ba1d4fe98b84b728b1466cad829351bf4856b10
|
4
|
+
data.tar.gz: d66d4d918d49e0fa7959aefff1b413e46503e310e73f60746eeea5bf1f1f9233
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ada36e48931de8d30f980ec791a4488616220c53b1b2df8d4d09a763f725a1a9f21d5c918747a0500afc2d58a29aa4b14b486f06e5be2adaeeea7c25da1fe18
|
7
|
+
data.tar.gz: dfc614d39850112351ccb81a060cea0d69109ab8174aa50405505ca6dad85a06ddd320383d006eaa4e6fca98898a4e81de9d83d64e6d1db0dec980bf4ca7f3e4
|
data/README.md
CHANGED
@@ -1,40 +1,153 @@
|
|
1
|
-
|
1
|
+
![Zen by Aikido for Ruby](./docs/banner.svg)
|
2
2
|
|
3
|
-
|
3
|
+
# Zen, in-app firewall for Ruby | by Aikido
|
4
|
+
|
5
|
+
Zen, your in-app firewall for peace of mind—at runtime.
|
6
|
+
|
7
|
+
Zen by Aikido is an embedded Web Application Firewall that autonomously protects
|
8
|
+
Ruby on Rails apps against common and critical attacks.
|
9
|
+
|
10
|
+
It protects your Rails apps by preventing user input containing dangerous
|
11
|
+
strings, preventing SQL injection and SSRF attacks. It runs embedded on your
|
12
|
+
Rails application, for simple installation and zero maintenance.
|
13
|
+
|
14
|
+
* 🛡️ [SQL injection attacks](https://www.aikido.dev/blog/the-state-of-sql-injections)
|
15
|
+
* 🛡️ [Server-side request forgery (SSRF)](https://github.com/AikidoSec/firewall-node/blob/main/docs/ssrf.md)
|
16
|
+
* 🛡️ [Command injection attacks](https://owasp.org/www-community/attacks/Command_Injection) (coming soon)
|
17
|
+
* 🛡️ [Path traversal attacks](https://owasp.org/www-community/attacks/Path_Traversal)
|
18
|
+
* 🛡️ [NoSQL injection attacks](https://www.aikido.dev/blog/web-application-security-vulnerabilities) (coming soon)
|
19
|
+
|
20
|
+
Zen operates autonomously on the same server as your Rails app to:
|
21
|
+
|
22
|
+
* ✅ Secure your app like a classic web application firewall (WAF), but with none of the infrastructure or cost.
|
23
|
+
* ✅ Rate limit specific API endpoints by IP or by user.
|
24
|
+
* ✅ Allow you to block specific users manually.
|
25
|
+
|
26
|
+
## Supported libraries and frameworks
|
27
|
+
|
28
|
+
Zen for Ruby 2.7+ is compatible with:
|
29
|
+
|
30
|
+
### Database drivers
|
31
|
+
|
32
|
+
* ✅ [sqlite3](https://github.com/sparklemotion/sqlite3-ruby) 1.x, 2.x
|
33
|
+
* ✅ [pg](https://github.com/ged/ruby-pg) 1.x
|
34
|
+
* ✅ [trilogy](https://github.com/trilogy-libraries/trilogy) 2.x
|
35
|
+
* ✅ [mysql2](https://github.com/brianmario/mysql2) 0.x
|
36
|
+
|
37
|
+
### ORMs and Query Builders
|
38
|
+
|
39
|
+
See list above for supported database drivers.
|
40
|
+
|
41
|
+
* ✅ [ActiveRecord](https://github.com/rails/rails)
|
42
|
+
* ✅ [Sequel](https://github.com/jeremyevans/sequel)
|
43
|
+
|
44
|
+
### HTTP Clients
|
45
|
+
|
46
|
+
* ✅ [net-http](https://github.com/ruby/net-http)
|
47
|
+
* ✅ [http.rb](https://github.com/httprb/http) 1.x, 2.x, 3.x, 4.x, 5.x
|
48
|
+
* ✅ [httpx](https://gitlab.com/os85/httpx) 1.x (1.1.3+)
|
49
|
+
* ✅ [HttpClient](https://github.com/nahi/httpclient) 2.x, 3.x
|
50
|
+
* ✅ [excon](https://github.com/excon/excon) 0.x (0.50.0+), 1.x
|
51
|
+
* ✅ [patron](https://github.com/toland/patron) 0.x (0.6.4+)
|
52
|
+
* ✅ [typhoeus](https://github.com/typhoeus/typhoeus) 0.x (0.5.0+), 1.x
|
53
|
+
* ✅ [curb](https://github.com/taf2/curb) 0.x (0.2.3+), 1.x
|
54
|
+
* ✅ [em-http-request](https://github.com/igrigorik/em-http-request) 1.x
|
55
|
+
* ✅ [async-http](https://github.com/igrigorik/em-http-request) 0.x (0.70.0+)
|
4
56
|
|
5
57
|
## Installation
|
6
58
|
|
7
|
-
|
59
|
+
We recommend testing Zen locally or on staging before deploying to production.
|
60
|
+
|
61
|
+
```
|
62
|
+
bundle add aikido-zen
|
63
|
+
```
|
64
|
+
|
65
|
+
or, if not using bundler:
|
66
|
+
|
67
|
+
```
|
68
|
+
gem install aikido-zen
|
69
|
+
```
|
8
70
|
|
9
|
-
|
71
|
+
For framework specific instructions, check out our docs:
|
10
72
|
|
11
|
-
|
73
|
+
* [Ruby on Rails apps](docs/rails.md)
|
12
74
|
|
13
|
-
|
75
|
+
## Running in production (blocking) mode
|
14
76
|
|
15
|
-
|
77
|
+
By default, Zen will only detect and report attacks to Aikido.
|
16
78
|
|
17
|
-
|
18
|
-
`rake test` to run the tests. You can also run `bin/console` for an interactive
|
19
|
-
prompt that will allow you to experiment.
|
79
|
+
To block requests, set the `AIKIDO_BLOCK` environment variable to `true`.
|
20
80
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
81
|
+
See [Reporting to Aikido](#reporting-to-your-aikido-security-dashboard) to learn
|
82
|
+
how to send events to Aikido.
|
83
|
+
|
84
|
+
## Reporting to your Aikido Security dashboard
|
85
|
+
|
86
|
+
> Aikido is your no nonsense application security platform. One central system
|
87
|
+
> that scans your source code & cloud, shows you what vulnerabilities matter,
|
88
|
+
> and how to fix them - fast. So you can get back to building.
|
89
|
+
|
90
|
+
Zen is a new product by Aikido. Built for developers to level up their security.
|
91
|
+
While Aikido scans, get Zen for always-on protection.
|
92
|
+
|
93
|
+
You can use some of Zen’s features without Aikido, of course. Peace of mind is
|
94
|
+
just a few lines of code away.
|
95
|
+
|
96
|
+
But you will get the most value by reporting your data to Aikido.
|
97
|
+
|
98
|
+
You will need an Aikido account and a token to report events to Aikido. If you
|
99
|
+
don't have an account, you can sign up for free.
|
100
|
+
|
101
|
+
Here's how:
|
102
|
+
|
103
|
+
* Log in to your Aikido account.
|
104
|
+
* Go to "Zen" on the sidebar.
|
105
|
+
* Click on "Add App".
|
106
|
+
* Choose a name for your App.
|
107
|
+
* Click "Continue to Install"
|
108
|
+
* Click "Generate Token".
|
109
|
+
* Copy the token.
|
110
|
+
* Set the token as an environment variable, `AIKIDO_TOKEN`, using
|
111
|
+
[dotenv](https://github.com/bkeepers/dotenv) or another method
|
112
|
+
of your choosing.
|
113
|
+
|
114
|
+
## Performance
|
115
|
+
|
116
|
+
We run a benchmark on every commit to ensure Zen has a minimal impact on your
|
117
|
+
application's performance.
|
118
|
+
|
119
|
+
For example, here's a benchmark that runs a single GET request to a Rails
|
120
|
+
endpoint that performs a single SQL SELECT query:
|
121
|
+
|
122
|
+
| Without Zen | With Zen | Difference |
|
123
|
+
|------------------|---------------|---------------|
|
124
|
+
| 3.527ms | 3.583ms | +0.056ms |
|
125
|
+
|
126
|
+
Using Ruby 3.3, Rails 7.1, SQLite 1.7, running on a MacBook Pro M1 Pro. Results
|
127
|
+
will vary based on hardware.
|
128
|
+
|
129
|
+
See [benchmarks](benchmarks) for more information.
|
130
|
+
|
131
|
+
## Bug bounty program
|
132
|
+
|
133
|
+
Our bug bounty program is public and can be found by all registered Intigriti
|
134
|
+
users at: https://app.intigriti.com/researcher/programs/aikido/aikidoruntime
|
26
135
|
|
27
136
|
## Contributing
|
28
137
|
|
29
|
-
|
30
|
-
intended to be a safe, welcoming space for collaboration, and contributors are
|
31
|
-
expected to adhere to the [code of conduct][coc].
|
138
|
+
See [CONTRIBUTING.md](.github/CONTRIBUTING.md) for more information.
|
32
139
|
|
33
140
|
## Code of Conduct
|
34
141
|
|
35
|
-
|
36
|
-
|
37
|
-
|
142
|
+
See [CODE_OF_CONDUCT.md](.github/CODE_OF_CONDUCT.md) for more information.
|
143
|
+
|
144
|
+
## License
|
145
|
+
|
146
|
+
This program is offered under a commercial and under the AGPL license. You can
|
147
|
+
be released from the requirements of the AGPL license by purchasing a commercial
|
148
|
+
license. Buying such a license is mandatory as soon as you develop commercial
|
149
|
+
activities involving the Zen software without disclosing the source code of your
|
150
|
+
own applications.
|
38
151
|
|
39
|
-
|
40
|
-
|
152
|
+
For more information, please contact Aikido Security at this address:
|
153
|
+
support@aikido.dev or create an account at https://app.aikido.dev.
|
data/Rakefile
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Benchmarking Zen for Ruby
|
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
|
+
|
6
|
+
We use [Grafana K6](https://k6.io) for these. For each sample application we
|
7
|
+
include in this repo under [sample_apps](../sample_apps), you should find
|
8
|
+
a script here that runs certain benchmarks against that app.
|
9
|
+
|
10
|
+
To run all the benchmarks, run the following from the root of the project:
|
11
|
+
|
12
|
+
```
|
13
|
+
$ bundle exec rake bench
|
14
|
+
```
|
15
|
+
|
16
|
+
In order to run a benchmarks against a single application, run the following
|
17
|
+
from the root of the project:
|
18
|
+
|
19
|
+
```
|
20
|
+
$ bundle exec rake bench:{app}:run
|
21
|
+
```
|
22
|
+
|
23
|
+
For example, for the `rails7.1_sql_injection` application:
|
24
|
+
|
25
|
+
```
|
26
|
+
$ bundle exec rake bench:rails7.1_sql_injection:run
|
27
|
+
```
|
@@ -0,0 +1,74 @@
|
|
1
|
+
import http from 'k6/http';
|
2
|
+
import { textSummary } from 'https://jslib.k6.io/k6-summary/0.0.2/index.js';
|
3
|
+
import { check, sleep, fail } from 'k6';
|
4
|
+
import exec from 'k6/execution';
|
5
|
+
import { Trend } from 'k6/metrics';
|
6
|
+
|
7
|
+
const HTTP = {
|
8
|
+
withZen: {
|
9
|
+
get: (path, ...args) => http.get("http://localhost:3001" + path, ...args),
|
10
|
+
post: (path, ...args) => http.post("http://localhost:3001" + path, ...args)
|
11
|
+
},
|
12
|
+
withoutZen: {
|
13
|
+
get: (path, ...args) => http.get("http://localhost:3002" + path, ...args),
|
14
|
+
post: (path, ...args) => http.post("http://localhost:3002" + path, ...args)
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
function test(name, fn) {
|
19
|
+
const duration = tests[name].duration;
|
20
|
+
const overhead = tests[name].overhead;
|
21
|
+
|
22
|
+
const withZen = fn(HTTP.withZen);
|
23
|
+
const withoutZen = fn(HTTP.withoutZen);
|
24
|
+
|
25
|
+
const timeWithZen = withZen.timings.duration,
|
26
|
+
timeWithoutZen = withoutZen.timings.duration;
|
27
|
+
|
28
|
+
duration.add(timeWithZen - timeWithoutZen);
|
29
|
+
|
30
|
+
const ratio = withZen.timings.duration / withoutZen.timings.duration;
|
31
|
+
overhead.add(100 * (timeWithZen - timeWithoutZen) / timeWithoutZen)
|
32
|
+
}
|
33
|
+
|
34
|
+
const defaultHeaders = {
|
35
|
+
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
|
36
|
+
};
|
37
|
+
|
38
|
+
const tests = {
|
39
|
+
test_post_page_with_json_body: {
|
40
|
+
duration: new Trend("test_post_page_with_json_body"),
|
41
|
+
overhead: new Trend("test_overhead_with_json_body")
|
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
|
+
}
|
51
|
+
}
|
52
|
+
export const options = {
|
53
|
+
vus: 1, // Number of virtual users
|
54
|
+
iterations: 200,
|
55
|
+
thresholds: {
|
56
|
+
test_post_page_with_json_body: ["med<10"],
|
57
|
+
test_get_page_without_attack: ["med<10"],
|
58
|
+
test_get_page_with_sql_injection: ["med<10"],
|
59
|
+
}
|
60
|
+
};
|
61
|
+
|
62
|
+
const expectAttack = http.expectedStatuses(500);
|
63
|
+
|
64
|
+
export default function () {
|
65
|
+
test("test_post_page_with_json_body",
|
66
|
+
(http) => http.post("/cats", JSON.stringify({cat: {name: "Féline Dion"}}), {
|
67
|
+
headers: {"Content-Type": "application/json"}
|
68
|
+
})
|
69
|
+
)
|
70
|
+
test("test_get_page_without_attack", (http) => http.get("/cats"))
|
71
|
+
test("test_get_page_with_sql_injection", (http) =>
|
72
|
+
http.get("/cats/1'%20OR%20''='", {responseCallback: expectAttack})
|
73
|
+
)
|
74
|
+
}
|