Add rack-attack to throttle login actions

This also fixes CVE-2024-0227 for 2FA brute force

See: https://blog.inhq.net/posts/totp-CVE-2024-0227/
This commit is contained in:
Benjamin Neff 2024-06-15 03:57:12 +02:00
parent 0d41b7ca13
commit 70e293ba94
No known key found for this signature in database
GPG key ID: 971464C3F1A90194
4 changed files with 38 additions and 0 deletions

View file

@ -42,6 +42,11 @@ We recommend setting up new pods using Ruby 3.3, and updating existing pods to t
If you're currently running your production pod with `./script/server` in a tmux or something similar, please be careful. We made some internal changes that result in the script no longer automatically restarting the server if it crashes - instead, it will just shut down. We strongly recommend running your pod using your system's unit manager, for example with [this systemd unit](https://wiki.diasporafoundation.org/Automatic_startup_methods#Recommended:_systemd).
## Security
* Fix a potential 2FA brute force attack ([CVE-2024-0227](https://github.com/devise-two-factor/devise-two-factor/security/advisories/GHSA-chcr-x7hc-8fp8)).
Thanks to Christian Reitter ([Radically Open Security](https://www.radicallyopensecurity.com/)) and Chris MacNaughton ([Centauri Solutions](https://centauri.solutions)).
## Refactor
* Add bootstrapping for using ECMAScript 6 with automatic transpiling for compatibility [#7581](https://github.com/diaspora/diaspora/pull/7581) [#8397](https://github.com/diaspora/diaspora/pull/8397)
* Remove backporting of mention syntax [#7788](https://github.com/diaspora/diaspora/pull/7788)

View file

@ -115,6 +115,10 @@ gem "redcarpet", "3.6.0"
gem "ruby-oembed", "0.17.0"
gem "twitter-text", "3.1.0"
# Rate limitting
gem "rack-attack", "6.7.0"
# RTL support
gem "string-direction", "1.2.2"

View file

@ -509,6 +509,8 @@ GEM
raabro (1.4.0)
racc (1.8.0)
rack (2.2.9)
rack-attack (6.7.0)
rack (>= 1.0, < 4)
rack-cors (2.0.2)
rack (>= 2.0.0)
rack-google-analytics (1.2.0)
@ -841,6 +843,7 @@ DEPENDENCIES
pry
pry-byebug
puma (= 6.4.2)
rack-attack (= 6.7.0)
rack-cors (= 2.0.2)
rack-google-analytics (= 1.2.0)
rack-piwik (= 0.3.0)

View file

@ -0,0 +1,26 @@
# frozen_string_literal: true
module Rack
class Attack
class Request
def throttleable_ip
parsed = IPAddr.new(ip)
if parsed.ipv6? && !parsed.ipv4_mapped?
# Throttle all requests from the same /64 IPv6 subnet
parsed.mask(64)
else
parsed
end.to_s
end
end
throttle("logins/ip", limit: 20, period: 5.minutes) do |req|
req.throttleable_ip if req.post? && req.path.start_with?("/users/sign_in")
end
throttle("otp/user_id", limit: 20, period: 1.hour) do |req|
req.session[:otp_user_id] if req.post? && req.path.start_with?("/users/sign_in") && req.session[:otp_user_id]
end
end
end