# frozen_string_literal: true
require “rails_helper”
RSpec.describe “Rack::Attack”, type: :request do
describe "req/ip throttle" do it "rate limits requests from spammy clients" do 300.times do get root_url expect(response).not_to have_http_status(:too_many_requests) end get root_url expect(response).to have_http_status(:too_many_requests) end end
<%- if devise? -%>
describe "logins/ip throttle" do it "rate limits login requests based off ip address" do 5.times do post new_user_session_path, params: { user: { email: Faker::Internet.email, password: Faker::Internet.password } } end post new_user_session_path, params: { user: { email: Faker::Internet.email, password: Faker::Internet.password } } expect(response).to have_http_status(:too_many_requests) end end describe "logins/email throttle" do it "rate limits login requests based off email address" do valid_email_parameters = { user: { email: Faker::Internet.email, password: Faker::Internet.password } } 5.times do |n| post new_user_session_path, params: valid_email_parameters, headers: { "REMOTE_ADDR" => format("120.0.1.%<n>d", n: n) } end post new_user_session_path, params: valid_email_parameters expect(response).to have_http_status(:too_many_requests) end end describe "registrations/ip throttle" do it "rate limits regstration requests based off ip address" do 5.times do put user_registration_path, params: update_user_email_params end put user_registration_path, params: update_user_email_params expect(response).to have_http_status(:too_many_requests) end end
<%- end -%>
describe "fail2ban/pentesters blocklist" do PENTESTING_PATHS = %w[ /etc/passwd /bad_endpoint?secret_file=/etc/passwd /wp-admin /wp-login /example.php ].freeze DENIAL_URL = "https://www.youtube.com/watch?v=dQw4w9WgXcQ" PENTESTING_PATHS.each do |pentesting_path| it "blocks clients after repeat visits to #{pentesting_path}" do 2.times do get pentesting_path expect(response).to have_http_status(:moved_permanently) expect(response).to redirect_to(root_url) end get root_url expect(response).not_to redirect_to(DENIAL_URL) get pentesting_path expect(response).to have_http_status(:moved_permanently) expect(response).to redirect_to(root_url) get root_url expect(response).to have_http_status(:found) expect(response).to redirect_to(DENIAL_URL) end end PENTESTING_PATHS.shuffle.combination(3).to_a.sample.tap do |url_a, url_b, url_c| it "shares the visit count between pentesting routes (e.g. #{url_a}, #{url_b}, #{url_c})" do get url_a get url_b get url_c get root_url expect(response).to have_http_status(:found) expect(response).to redirect_to(DENIAL_URL) end end end
end