1+ return unless Rails . env . production?
2+
3+ class Rack ::Attack
4+
5+ # IP list available at https://www.cloudflare.com/en-gb/ips/
6+ CLOUDFLARE_IPS = [
7+ IPAddr . new ( "173.245.48.0/20" ) ,
8+ IPAddr . new ( "103.21.244.0/22" ) ,
9+ IPAddr . new ( "103.22.200.0/22" ) ,
10+ IPAddr . new ( "103.31.4.0/22" ) ,
11+ IPAddr . new ( "141.101.64.0/18" ) ,
12+ IPAddr . new ( "108.162.192.0/18" ) ,
13+ IPAddr . new ( "190.93.240.0/20" ) ,
14+ IPAddr . new ( "188.114.96.0/20" ) ,
15+ IPAddr . new ( "197.234.240.0/22" ) ,
16+ IPAddr . new ( "198.41.128.0/17" ) ,
17+ IPAddr . new ( "162.158.0.0/15" ) ,
18+ IPAddr . new ( "104.16.0.0/13" ) ,
19+ IPAddr . new ( "104.24.0.0/14" ) ,
20+ IPAddr . new ( "172.64.0.0/13" ) ,
21+ IPAddr . new ( "131.0.72.0/22" ) ,
22+ IPAddr . new ( "2400:cb00::/32" ) ,
23+ IPAddr . new ( "2606:4700::/32" ) ,
24+ IPAddr . new ( "2803:f800::/32" ) ,
25+ IPAddr . new ( "2405:b500::/32" ) ,
26+ IPAddr . new ( "2405:8100::/32" ) ,
27+ IPAddr . new ( "2a06:98c0::/29" ) ,
28+ IPAddr . new ( "2c0f:f248::/32" )
29+ ]
30+
31+ blocklist ( "block non-cloudflare traffic" ) do |req |
32+ ip = IPAddr . new ( req . ip )
33+ allowed = CLOUDFLARE_IPS . any? { |range | range . include? ( ip ) }
34+ !allowed
35+ end
36+
37+ # Below: default Rack Attack config setup (mostly unused)
38+ ### Configure Cache ###
39+
40+ # If you don't want to use Rails.cache (Rack::Attack's default), then
41+ # configure it here.
42+ #
43+ # Note: The store is only used for throttling (not blocklisting and
44+ # safelisting). It must implement .increment and .write like
45+ # ActiveSupport::Cache::Store
46+
47+ # Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
48+
49+ ### Throttle Spammy Clients ###
50+
51+ # If any single client IP is making tons of requests, then they're
52+ # probably malicious or a poorly-configured scraper. Either way, they
53+ # don't deserve to hog all of the app server's CPU. Cut them off!
54+ #
55+ # Note: If you're serving assets through rack, those requests may be
56+ # counted by rack-attack and this throttle may be activated too
57+ # quickly. If so, enable the condition to exclude them from tracking.
58+
59+ # Throttle all requests by IP (60rpm)
60+ #
61+ # Key: "rack::attack:#{Time.now.to_i/:period}:req/ip:#{req.ip}"
62+ throttle ( 'req/ip' , limit : 300 , period : 5 . minutes ) do |req |
63+ req . ip # unless req.path.start_with?('/assets')
64+ end
65+
66+ ### Prevent Brute-Force Login Attacks ###
67+
68+ # The most common brute-force login attack is a brute-force password
69+ # attack where an attacker simply tries a large number of emails and
70+ # passwords to see if any credentials match.
71+ #
72+ # Another common method of attack is to use a swarm of computers with
73+ # different IPs to try brute-forcing a password for a specific account.
74+
75+ # Throttle POST requests to /login by IP address
76+ #
77+ # Key: "rack::attack:#{Time.now.to_i/:period}:logins/ip:#{req.ip}"
78+ # throttle('logins/ip', limit: 5, period: 20.seconds) do |req|
79+ # if req.path == '/login' && req.post?
80+ # req.ip
81+ # end
82+ # end
83+
84+ # Throttle POST requests to /login by email param
85+ #
86+ # Key: "rack::attack:#{Time.now.to_i/:period}:logins/email:#{normalized_email}"
87+ #
88+ # Note: This creates a problem where a malicious user could intentionally
89+ # throttle logins for another user and force their login requests to be
90+ # denied, but that's not very common and shouldn't happen to you. (Knock
91+ # on wood!)
92+ # throttle('logins/email', limit: 5, period: 20.seconds) do |req|
93+ # if req.path == '/login' && req.post?
94+ # # Normalize the email, using the same logic as your authentication process, to
95+ # # protect against rate limit bypasses. Return the normalized email if present, nil otherwise.
96+ # req.params['email'].to_s.downcase.gsub(/\s+/, "").presence
97+ # end
98+ # end
99+
100+ ### Custom Throttle Response ###
101+
102+ # By default, Rack::Attack returns an HTTP 429 for throttled responses,
103+ # which is just fine.
104+ #
105+ # If you want to return 503 so that the attacker might be fooled into
106+ # believing that they've successfully broken your app (or you just want to
107+ # customize the response), then uncomment these lines.
108+ # self.throttled_responder = lambda do |env|
109+ # [ 503, # status
110+ # {}, # headers
111+ # ['']] # body
112+ # end
113+ end
0 commit comments