aikido-zen 0.1.0.alpha4-x86_64-linux → 0.1.0-x86_64-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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +136 -23
  3. data/Rakefile +4 -0
  4. data/benchmarks/README.md +27 -0
  5. data/benchmarks/rails7.1_sql_injection.js +74 -0
  6. data/docs/banner.svg +203 -0
  7. data/docs/config.md +123 -0
  8. data/docs/rails.md +70 -0
  9. data/lib/aikido/zen/actor.rb +1 -1
  10. data/lib/aikido/zen/agent/heartbeats_manager.rb +66 -0
  11. data/lib/aikido/zen/agent.rb +98 -112
  12. data/lib/aikido/zen/collector/hosts.rb +15 -0
  13. data/lib/aikido/zen/collector/routes.rb +64 -0
  14. data/lib/aikido/zen/{stats → collector}/sink_stats.rb +1 -1
  15. data/lib/aikido/zen/collector/stats.rb +111 -0
  16. data/lib/aikido/zen/{stats → collector}/users.rb +6 -2
  17. data/lib/aikido/zen/collector.rb +117 -0
  18. data/lib/aikido/zen/config.rb +17 -11
  19. data/lib/aikido/zen/context.rb +8 -1
  20. data/lib/aikido/zen/errors.rb +3 -1
  21. data/lib/aikido/zen/event.rb +7 -4
  22. data/lib/aikido/zen/libzen-v0.1.30.x86_64.so +0 -0
  23. data/lib/aikido/zen/middleware/set_context.rb +4 -1
  24. data/lib/aikido/zen/rails_engine.rb +27 -18
  25. data/lib/aikido/zen/request/schema/builder.rb +0 -2
  26. data/lib/aikido/zen/request.rb +6 -0
  27. data/lib/aikido/zen/runtime_settings.rb +6 -11
  28. data/lib/aikido/zen/sinks/action_controller.rb +64 -0
  29. data/lib/aikido/zen/sinks.rb +1 -0
  30. data/lib/aikido/zen/version.rb +2 -2
  31. data/lib/aikido/zen/worker.rb +82 -0
  32. data/lib/aikido/zen.rb +55 -50
  33. data/tasklib/bench.rake +70 -0
  34. metadata +19 -9
  35. data/CODE_OF_CONDUCT.md +0 -132
  36. data/lib/aikido/zen/libzen-v0.1.26.x86_64.so +0 -0
  37. data/lib/aikido/zen/stats/routes.rb +0 -53
  38. data/lib/aikido/zen/stats.rb +0 -171
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb3e9def57efa65f36ad936f752fea0e61695252c185e87ca9c1f91fa675b7e1
4
- data.tar.gz: 47effea853a3d7f58549ed4c0a98a37d1f6811f8e64888bcc54aad1fd43b9008
3
+ metadata.gz: 0f0b2a3174ea5cb98412aad7981aa6b669490e4c125cb23d179419027a349c7d
4
+ data.tar.gz: 6009a16031c7935f9243b99ef64d9735d692f705d18ba612dc214eafffb1aa7b
5
5
  SHA512:
6
- metadata.gz: b2c3136e777008f9009e529e41fa3bcc418326e8dccdb3a862acc67eea33825099fe8215ddf9d4d52e90349c6ebed109bf2a49fcfb895e392a2e91ee7183a1bf
7
- data.tar.gz: 8ce803adf9897680dcd7ab20ee9f4ced0145727815fad10f97cf40fe6a6325860de1c93e78686ddf48a85dc32d19a2ecce04259856acdb31bdac6fc54d0a21a7
6
+ metadata.gz: ecf36ae3339b10fbf6b34c5baaeb071cb7d4c5785ddfb593af1145bd4063f617d9869ddad3a99361ebfeaea914bd9d32c2a7c53dad6a4772b453dc23f96f200d
7
+ data.tar.gz: f0c4833d629ebdf1ec2ad07df541bc02c88e96c57a76a14537bbf6df875eccd0c5440b1f2f6831c5cfb77336514365fe6deecf6a6c25466d5e0576e1c2478006
data/README.md CHANGED
@@ -1,40 +1,153 @@
1
- # Aikido::Firewall
1
+ ![Zen by Aikido for Ruby](./docs/banner.svg)
2
2
 
3
- TODO: Write me :)
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
- Install the gem and add to the application's Gemfile by executing:
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
- $ bundle add aikido-firewall
71
+ For framework specific instructions, check out our docs:
10
72
 
11
- If bundler is not being used to manage dependencies, install the gem by executing:
73
+ * [Ruby on Rails apps](docs/rails.md)
12
74
 
13
- $ gem install aikido-firewall
75
+ ## Running in production (blocking) mode
14
76
 
15
- ## Development
77
+ By default, Zen will only detect and report attacks to Aikido.
16
78
 
17
- After checking out the repo, run `bin/setup` to install dependencies. Then, run
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
- To install this gem onto your local machine, run `bundle exec rake install`. To
22
- release a new version, update the version number in `version.rb`, and then run
23
- `bundle exec rake release`, which will create a git tag for the version, push
24
- git commits and the created tag, and push the `.gem` file to
25
- [rubygems.org](https://rubygems.org).
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
- Bug reports and pull requests are welcome [on GitHub][repo]. This project is
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
- Everyone interacting in the `Aikido::Firewall` project's codebases, issue
36
- trackers, chat rooms and mailing lists is expected to follow the [code of
37
- conduct][coc].
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
- [repo]: https://github.com/aikidosec/firewall-ruby
40
- [coc]: https://github.com/aikidosec/firewall-ruby/blob/main/CODE_OF_CONDUCT.md
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
@@ -6,6 +6,10 @@ require "standard/rake"
6
6
  require "rake/clean"
7
7
 
8
8
  load "tasklib/libzen.rake"
9
+ load "tasklib/bench.rake"
10
+
11
+ desc "Run all benchmarks"
12
+ task bench: "bench:default"
9
13
 
10
14
  namespace :build do
11
15
  desc "Ensure Gemfile.lock is up-to-date"
@@ -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
+ }