Skip to content

Commit

Permalink
Updated Rack Attack configuration to address vulnerabilities in passw…
Browse files Browse the repository at this point in the history
…ord updates.

Changes:
    The fix involves adding a new Rack Attack rule "profile_updates/ip" and
    rewriting the body of the rules "password_resets/ip" and "logins/ip" so
    the the request ip is returned if the rule is triggered.
  • Loading branch information
John Pinto committed Oct 14, 2024
1 parent 56759df commit 27d91aa
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Changelog

- Updated Rack Attack configuration to address vulnerabilities in password updates.

## v4.2.0

**Note this upgrade is mainly a migration from Bootstrap 3 to Bootstrap 5.**
Expand Down
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ gem 'jwt'
gem 'pundit'

# Gem for throttling malicious attacks
gem 'dalli', '~> 3.2', '>= 3.2.8'
gem 'rack-attack', '~> 6.6', '>= 6.6.1'

# ========== #
Expand Down
26 changes: 20 additions & 6 deletions config/initializers/rack_attack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,35 @@
Rack::Attack.enabled = true

# Cache store required to work.
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new # defaults to Rails.cache
# Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new # defaults to Rails.cache

Rack::Attack.cache.store = ActiveSupport::Cache::MemCacheStore.new
# Rack::Attack.cache.store = ActiveSupport::Cache::FileStore.new("/tmp/cache")

# Throttle should send a 429 Error responsec code and display public/429.html
Rack::Attack.throttled_responder = lambda do |_env|
html = ActionView::Base.empty.render(file: 'public/429.html')
[429, { 'Content-Type' => 'text/html' }, [html]]
end

# Throttle attempts to a particular path. 2 POSTs to /users/password every 30 seconds
Rack::Attack.throttle "password_resets/ip", limit: 2, period: 30.seconds do |req|
req.post? && req.path == "/users/password" && req.ip
end
# # Throttle attempts to a particular path. 2 POSTs to /users/password every 30 seconds
# Rack::Attack.throttle "password_resets/ip", limit: 2, period: 30.seconds do |req|
# req.ip if req.post? && req.path == "/users/password"
# end

# Throttle attempts to a particular path. 4 POSTs to /users/sign_in every 30 seconds
Rack::Attack.throttle "logins/ip", limit: 4, period: 30.seconds do |req|
# Don't apply sign-in rate-limiting to test environment
req.post? && req.path == "/users/sign_in" && req.ip unless Rails.env.test?
(req.ip if req.post? && req.path == "/users/sign_in") unless Rails.env.test?
end

# Throttle attempts to a particular path. 3 POST or PUTS to /users every 20 seconds
# This includes password updates. This is to prevent brute force attacks on user.accept_terms.
# This replaces the previous throttle on /users/password and is extended to other profile update.
# Exclude test environment.
Rack::Attack.throttle "profile_updates", limit: 3, period: 20.seconds do |req|
if !Rails.env.test? && req.path != "/users/sign_in" && (req.put? || req.post?) && req.path.start_with?("/users")
puts "Throttling #{req.ip} for #{req.path}"
req.ip
end
end

0 comments on commit 27d91aa

Please sign in to comment.