Skip to content

Commit

Permalink
Maintenance: Improve configuration of rack_attack.
Browse files Browse the repository at this point in the history
(cherry picked from commit a41170308a8ba0c66465c74ca53217a3bbd68537)
  • Loading branch information
mgruner committed Jul 4, 2022
1 parent 0c1d519 commit ccff135
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 6 deletions.
10 changes: 5 additions & 5 deletions config/initializers/rack_attack.rb
Expand Up @@ -5,13 +5,13 @@
#
API_V1_USERS__PASSWORD_RESET_PATH = '/api/v1/users/password_reset'.freeze
Rack::Attack.throttle('limit password reset requests per username', limit: 3, period: 1.minute.to_i) do |req|
if req.path == API_V1_USERS__PASSWORD_RESET_PATH && req.post?
if req.path.start_with?(API_V1_USERS__PASSWORD_RESET_PATH) && req.post?
# Normalize to protect against rate limit bypasses.
req.params['username'].to_s.downcase.gsub(%r{\s+}, '')
end
end
Rack::Attack.throttle('limit password reset requests per source IP address', limit: 3, period: 1.minute.to_i) do |req|
if req.path == API_V1_USERS__PASSWORD_RESET_PATH && req.post?
if req.path.start_with?(API_V1_USERS__PASSWORD_RESET_PATH) && req.post?
req.ip
end
end
Expand All @@ -22,19 +22,19 @@
API_V1_FORM_SUBMIT_PATH = '/api/v1/form_submit'.freeze
form_limit_by_ip_per_hour_proc = proc { Setting.get('form_ticket_create_by_ip_per_hour') || 20 }
Rack::Attack.throttle('form submits per IP and hour', limit: form_limit_by_ip_per_hour_proc, period: 1.hour.to_i) do |req|
if req.path == API_V1_FORM_SUBMIT_PATH
if req.path.start_with?(API_V1_FORM_SUBMIT_PATH)
req.ip
end
end
form_limit_by_ip_per_day_proc = proc { Setting.get('form_ticket_create_by_ip_per_day') || 240 }
Rack::Attack.throttle('form submits per IP and day', limit: form_limit_by_ip_per_day_proc, period: 1.day.to_i) do |req|
if req.path == API_V1_FORM_SUBMIT_PATH
if req.path.start_with?(API_V1_FORM_SUBMIT_PATH)
req.ip
end
end
form_limit_per_day_proc = proc { Setting.get('form_ticket_create_per_day') || 5000 }
Rack::Attack.throttle('form submits per day', limit: form_limit_per_day_proc, period: 1.day.to_i) do |req|
if req.path == API_V1_FORM_SUBMIT_PATH
if req.path.start_with?(API_V1_FORM_SUBMIT_PATH)
req.path
end
end
3 changes: 2 additions & 1 deletion spec/requests/user/password_reset_spec.rb
Expand Up @@ -34,7 +34,8 @@

it 'blocks due to source IP address throttling (multiple usernames)' do
15.times do
post api_v1_users_password_reset_path, params: { username: create(:user).login }, headers: { 'X-Forwarded-For': static_ipv4 }
# Ensure throttling even on modified path.
post "#{api_v1_users_password_reset_path}.json", params: { username: create(:user).login }, headers: { 'X-Forwarded-For': static_ipv4 }
end

expect(response).to have_http_status(:too_many_requests)
Expand Down

0 comments on commit ccff135

Please sign in to comment.