Add forgot_password_throttle (#19175)

This commit is contained in:
Mac Siri 2023-02-27 09:25:29 -05:00 committed by GitHub
parent db2b571bd6
commit 140f85695b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 5 deletions

View file

@ -34,6 +34,8 @@ module ValidRequest
"#{URL.protocol || request.protocol}#{request.host_with_port}#{options}"
when Proc
_compute_redirect_to_location request, instance_eval(&options)
when Array
url_for
else
url_for(options)
end.delete("\0\r\n")

View file

@ -46,6 +46,12 @@ module Rack
end
end
throttle("forgot_password_throttle", limit: 3, period: 1) do |request|
if request.path.starts_with?("/users/password") && request.post?
request.track_and_return_ip
end
end
throttle("api_write_throttle", limit: 1, period: 1) do |request|
api_endpoint = request.path.starts_with?("/api/")
if api_endpoint && (request.put? || request.post? || request.delete?)

View file

@ -1,17 +1,15 @@
require "rails_helper"
describe Rack, ".attack", type: :request, throttle: true do
describe Rack, ".attack", throttle: true, type: :request do
before do
cache_db = ActiveSupport::Cache.lookup_store(:redis_cache_store)
allow(Rails).to receive(:cache) { cache_db }
cache_db.redis.flushdb
allow(Rails).to receive(:cache) { ActiveSupport::Cache.lookup_store(:redis_cache_store) }
allow(Honeycomb).to receive(:add_field)
ENV["FASTLY_API_KEY"] = "12345"
end
after do
ENV["FASTLY_API_KEY"] = nil
Rails.cache.clear
end
describe "search_throttle" do
@ -171,4 +169,22 @@ describe Rack, ".attack", type: :request, throttle: true do
end
# rubocop:enable RSpec/AnyInstance, RSpec/ExampleLength
end
describe "forgot_password_throttle" do
it "throttles after 3 attempts" do
params = { user: { email: "yo@email.com" } }
admin_headers = { "HTTP_FASTLY_CLIENT_IP" => "5.6.7.8" }
Timecop.freeze do
3.times do
post "/users/password", params: params, headers: admin_headers
expect(response).to have_http_status(:found)
end
3.times do
post "/users/password", params: params, headers: admin_headers
expect(response).to have_http_status(:too_many_requests)
end
end
end
end
end