active_hashcash 0.3.2 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 27a33816eb2072dd2a76ed1f2844b1cd2f38915913f54a7ba4f855c5244ba1af
4
- data.tar.gz: d9e0ad4861a95a9140d68005186ffa15ea369da874c3753c9230fefae260d870
3
+ metadata.gz: ef5393e959b8a94792f35bc043c87542568398d3c9444a8e238ba6eafdbb3522
4
+ data.tar.gz: 74a51e94325581bf35113f81ccaccd696079bc43cfedc7f734ae5889ab0bb32f
5
5
  SHA512:
6
- metadata.gz: 22a0e700d62551411c188dc33062b6b7738f08cc6da250c779beef08db7c3d98ea987c2cffebdfd9fe83c9879da293b570124cc86508fd19a32e7743bf7e50f3
7
- data.tar.gz: ddf4aa8b020df59032e7f0711228279ecf375e903b46ce6a748c1b17d408277328db00f19b89955be639faaae7886e1ed700d2185fc91b520a547e0507afd3c4
6
+ metadata.gz: 5d0da77fac447177abebbf04a585927f42d7a100159bf9ab8df1305f1f88b9a394738c03f5a828177dea71f745a941b9bff7a8625c4cc8c5744fc735ef017cc2
7
+ data.tar.gz: 6845cb211b39fa5dfe0f0393df05ae7cd6e5b54f5e8f3e27e26a206f9853b026a7a557e0c5dbbf97e2eb1bc5468b4ef418cec31a9e20c98153b8027c13d30947
data/CHANGELOG.md CHANGED
@@ -1,8 +1,22 @@
1
1
  # Changelog of ActiveHashcash
2
2
 
3
+ ## 0.5.0 (2026-08-08)
4
+
5
+ - Fix stamp date mismatch by using server date instead of client
6
+ - Replace SHA-1 with SHA-256 for proof-of-work stamps
7
+ - Mine stamps in a Web Worker using pure JS SHA-256 (keeps the main thread unblocked)
8
+ - Support SHA-1 fallback on the backend for backward compatibility (via the `ext` stamp field)
9
+
10
+ ## 0.4.0 (2025-05-15)
11
+
12
+ - Prevent from password managers to submit the form before the stamp has been computed
13
+ - Added support for the "button" submit form tag
14
+ - Added Catalan language
15
+ - Added `base_controller_class` configuration option to allow specifying a custom base controller for the ActiveHashcash dashboard, enhancing flexibility in diverse application architectures.
16
+
3
17
  ## 0.3.2 (2024-08-29)
4
18
 
5
- - Fix methods conflitc by not including ActionView::Helpers::FormTagHelper
19
+ - Fix methods conflict by not including ActionView::Helpers::FormTagHelper
6
20
  - Sanitize params by forcing as a String
7
21
 
8
22
  ## 0.3.1 - 2024-04-04
data/README.md CHANGED
@@ -1,14 +1,14 @@
1
1
  # ActiveHashcash
2
2
 
3
- <img align="right" width="200px" src="logo.png" alt="Active Hashcash logo"/>
3
+ Protect Rails applications against bots and brute force attacks without annoying humans.
4
4
 
5
- ActiveHashcash protects Rails applications against bots and brute force attacks without annoying humans.
5
+ <div><img align="right" width="200px" src="logo.png" alt="Active Hashcash logo"/></div>
6
6
 
7
7
  Hashcash is proof-of-work algorithm, invented by Adam Back in 1997, to protect systems against denial of service attacks.
8
8
  ActiveHashcash is an easy way to protect any Rails application against brute force attacks and bots.
9
9
 
10
10
  The idea is to force clients to spend some time to solve a hard problem that is very easy to verify for the server.
11
- We have developped ActiveHashcash after seeing brute force attacks against our Rails application monitoring service [RorVsWild](https://rorvswild.com).
11
+ We have developed ActiveHashcash after seeing brute force attacks against our Rails application monitoring service [RorVsWild](https://rorvswild.com).
12
12
 
13
13
  ActiveHashcash is ideal to set up on sensitive forms such as login and registration.
14
14
  While the user is filling the form, the problem is solved in JavaScript and set the result into a hidden input text.
@@ -27,37 +27,40 @@ Here is a [demo on a registration form](https://www.rorvswild.com/session) :
27
27
 
28
28
  ---
29
29
 
30
- <img align="left" height="24px" src="rorvswild_logo.jpg" alt="RorVsWild logo"/>Made by <a href="https://www.rorvswild.com">RorVsWild</a>, performances & exceptions monitoring for Ruby on Rails applications.
30
+ <div><img align="left" height="24px" src="rorvswild_logo.jpg" alt="RorVsWild logo"/>Made by <a href="https://www.rorvswild.com">RorVsWild</a>, performances & exceptions monitoring for Ruby on Rails applications.</div>
31
31
 
32
32
  ---
33
33
 
34
34
  ## Installation
35
35
 
36
- Add this line to your application's Gemfile:
36
+ Add this line to your application's Gemfile and run `bundle install`:
37
37
 
38
38
  ```ruby
39
39
  gem "active_hashcash"
40
40
  ```
41
41
 
42
- Require hashcash from your JavaScript manifest.
42
+ Stamps are stored into the database to prevents from spending them more than once.
43
+ You must install and run a migration:
43
44
 
44
- ```js
45
- //= require hashcash
45
+ ```
46
+ rails active_hashcash:install:migrations
47
+ rails db:migrate
46
48
  ```
47
49
 
48
- OR
49
-
50
- Link hashcash to your JavaScript manifest and load it to your head.
50
+ Then you have to include ActiveHashcash and add a `before_action :check_hashcash` in you controller:
51
51
 
52
- ```js
53
- //= link hashcash.js
54
- ```
52
+ ```ruby
53
+ class SessionController < ApplicationController
54
+ include ActiveHashcash
55
55
 
56
- ```erb
57
- <%= javascript_include_tag "hashcash", "data-turbo-track": "reload", defer: true %>
56
+ # Only the action receiving the form needs to be protected
57
+ before_action :check_hashcash, only: :create
58
+ end
58
59
  ```
59
60
 
60
- Add a Hashcash hidden field into the form you want to protect.
61
+ The action `SessionController#create` is now protected.
62
+ The final step is compute the hashcash from the client side.
63
+ Start by adding a Hashcash hidden field into the form you want to protect.
61
64
 
62
65
  ```erb
63
66
  <form>
@@ -65,28 +68,28 @@ Add a Hashcash hidden field into the form you want to protect.
65
68
  </form>
66
69
  ```
67
70
 
68
- Then you have to define a `before_action :check_hashcash` in you controller.
69
-
70
- ```ruby
71
- class SessionController < ApplicationController
72
- include ActiveHashcash
71
+ Require hashcash from your JavaScript manifest.
73
72
 
74
- # Only the action receiving the form needs to be protected
75
- before_action :check_hashcash, only: :create
76
- end
73
+ ```js
74
+ //= require hashcash
77
75
  ```
78
76
 
79
- To customize some behaviour, you can override most of the methods which begins with `hashcash_`.
80
- Simply have a look to `active_hashcash.rb`.
81
-
82
- Stamps are stored into into the database to prevents from spending them more than once.
83
- You must run a migration:
77
+ Or, link hashcash to your JavaScript manifest and load it to your head.
84
78
 
79
+ ```js
80
+ //= link hashcash.js
85
81
  ```
86
- rails active_hashcash:install:migrations
87
- rails db:migrate
82
+
83
+ ```erb
84
+ <%= javascript_include_tag "hashcash", "data-turbo-track": "reload", defer: true %>
88
85
  ```
89
86
 
87
+ The hashcash stamp will be set in the hidden input once computed and the submit button enabled.
88
+
89
+ To customize behaviours, you can override methods of ActiveHashcash module.
90
+
91
+
92
+
90
93
  ### Dashboard
91
94
 
92
95
  There is a mountable dashboard which allows to see all spent stamps.
@@ -99,10 +102,22 @@ It's not mandatory, but useful for monitoring purpose.
99
102
  mount ActiveHashcash::Engine, at: "hashcash"
100
103
  ```
101
104
 
102
- ActiveHashcash cannot guess how you handle user authentication, because it is different for all Rails applications.
103
- So you have to monkey patch `ActiveHashcash::ApplicationController` in order to inject your own mechanism.
104
- The patch can be saved wherever you want.
105
- For example, I like to have all the patches in one place, so I put them in `lib/patches`.
105
+ ActiveHashcash cannot guess how user authentication is handled, because it is different for all Rails applications.
106
+ So here is 3 options.
107
+
108
+ #### Inheritance
109
+
110
+ By default ActiveHashcash extends `ActionController::Base`, but you can change it to any controller, such as `AdminController`.
111
+
112
+ ```ruby
113
+ # config/initializers/active_hashcash.rb
114
+ Rails.application.configure do
115
+ ActiveHashcash.base_controller_class = "AdminController"
116
+ end
117
+ ```
118
+ #### Monkey patching
119
+
120
+ Monkey patching `ActiveHashcash::ApplicationController` let you inject your own mechanism.
106
121
 
107
122
  ```ruby
108
123
  # lib/patches/active_hashcash.rb
@@ -118,9 +133,7 @@ ActiveHashcash::ApplicationController.class_eval do
118
133
  end
119
134
  ```
120
135
 
121
- Then you have to require the monkey patch.
122
- Because it's loaded via require, it won't be reloaded in development.
123
- Since you are not supposed to change this file often, it should not be an issue.
136
+ Then the patch has to be loaded from after initialization:
124
137
 
125
138
  ```ruby
126
139
  # config/application.rb
@@ -129,7 +142,9 @@ config.after_initialize do
129
142
  end
130
143
  ```
131
144
 
132
- If you use Devise, you can check the permission directly from routes.rb:
145
+ #### With Devise
146
+
147
+ Permission check can be achieved directly from routes.rb:
133
148
 
134
149
  ```ruby
135
150
  # config/routes.rb
@@ -141,7 +156,7 @@ end
141
156
  ### Before version 0.3.0
142
157
 
143
158
  You must have Redis in order to prevent double spent stamps. Otherwise it will be useless.
144
- It automatically tries to connect with the environement variables `ACTIVE_HASHCASH_REDIS_URL` or `REDIS_URL`.
159
+ It automatically tries to connect with the environment variables `ACTIVE_HASHCASH_REDIS_URL` or `REDIS_URL`.
145
160
  You can also manually set the URL with `ActiveHashcash.redis_url = redis://user:password@localhost:6379`.
146
161
 
147
162
  You should call `ActiveHashcash::Store#clean` once a day, to remove expired stamps.
@@ -157,23 +172,35 @@ rails db:migrate
157
172
 
158
173
  Complexity is the most important parameter. By default its value is 20 and requires most of the time 5 to 20 seconds to be solved on a decent laptop.
159
174
  The user won't wait that long, since he needs to fill the form while the problem is solving.
160
- Howevever, if your application includes people with slow and old devices, then consider lowering this value, to 16 or 18.
175
+ However, if your application includes people with slow and old devices, then consider lowering this value, to 16 or 18.
161
176
 
162
177
  You can change the minimum complexity with `ActiveHashcash.bits = 20`.
163
178
 
164
179
  Since version 0.3.0, the complexity increases with the number of stamps spent during le last 24H from the same IP address.
165
180
  Thus it becomes very efficient to slow down brute force attacks.
166
181
 
182
+ ## Testing
183
+
184
+ Browser tests submit the real form, so they have to compute a real stamp. At the default 16 bits this adds noticeable time to every submission and slows down your suite. Drop the complexity in the test environment so it finishes almost instantly:
185
+
186
+ ```ruby
187
+ # spec/rails_helper.rb (RSpec) or test/test_helper.rb (Minitest)
188
+ ActiveHashcash.bits = 2
189
+ ```
190
+
191
+ In controller tests, provide the hashcash this way:
192
+
193
+ ```ruby
194
+ post(url, params: {hashcash: ActiveHashcash::Stamp.mint(host).to_s})
195
+ ```
196
+
167
197
  ## Limitations
168
198
 
169
- The JavaScript implementation is 10 to 20 times slower than the official C version.
170
- I first used the SubtleCrypto API but it is surprisingly slower than a custom SHA1 implementation.
171
- Maybe I did in an unefficient way 2df3ba5?
172
- Another idea would be to compile the work algorithm in wasm.
199
+ The JavaScript implementation is slower than the official C version.
200
+ It uses a pure JS SHA-256 implementation running inside a Web Worker, which keeps the main thread responsive while mining.
201
+ A synchronous tight loop avoids the per-call async overhead of `crypto.subtle.digest()`, making it the fastest browser-side approach across Chrome and Safari.
173
202
 
174
- Unfortunately, I'm not a JavaScript expert.
175
- Maybe you have good JS skills to optimize it?
176
- Any help would be appreciate to better fights bots and brute for attacks!
203
+ No `crypto.subtle` or secure context (HTTPS) is required, so it works in any environment including plain HTTP during development.
177
204
 
178
205
  ## Contributing
179
206
 
@@ -183,4 +210,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/BaseSe
183
210
 
184
211
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
185
212
 
186
- Made by Alexis Bernard at [RorVsWild](https://www.rorvswild.com).
213
+ Made by [Alexis Bernard](https://alexis.bernard.io/).