bullet_train-core
bullet_train-core copied to clipboard
Protecting from spammy requests
As soon as a site goes live properly, it's going to be hit by an endless stream of spammy requests trying to hack into the server. These end up causing some annoyance and filling up the error logs (and using up the error logging capacity on nothing).
One simple solution is to install rack-attack
, and implement a simple blocklist:
class Rack::Attack
spammy_path_includes = [
'geoserver',
'/vpn',
'/webui',
'/PSIA',
'/HNAP1',
'/wp-',
'/xmlrpc',
'.php',
'wordpress',
'cgi-bin',
'.env',
'merchants',
'readme.html',
'license.txt',
'mailman',
'/remote',
'/owa',
'/ecp',
'_ignition',
'hetong.js',
'check.js'
]
Rack::Attack.blocklist('block hacking requests') do |req|
spammy_path_includes.select { |spam| req.path.downcase.include?(spam.downcase) }.any?
end
end
This blocks anyone accessing a URL that contains one of those strings somewhere in it. Possibly some of those should not be blocked, application-dependent, but for example just blocking all requests with "wp-" in them will remove 90% of the hack attempts which try to break into an insecure Wordpress blog. Worth noting the block is per-request. If a user mistakenly requests one of those they are not blocked permanently.
While at it, it may be worth adding the other two recommended rack-attack throttles:
### Throttle Spammy Clients ###
# If any single client IP is making tons of requests, then they're
# probably malicious or a poorly-configured scraper. Either way, they
# don't deserve to hog all of the app server's CPU. Cut them off!
#
# Note: If you're serving assets through rack, those requests may be
# counted by rack-attack and this throttle may be activated too
# quickly. If so, enable the condition to exclude them from tracking.
# Throttle all requests by IP (60rpm)
#
# Key: "rack::attack:#{Time.now.to_i/:period}:req/ip:#{req.ip}"
throttle('req/ip', limit: 300, period: 5.minutes) do |req|
req.ip unless req.path.start_with?('/assets')
end
### Prevent Brute-Force Login Attacks ###
# The most common brute-force login attack is a brute-force password
# attack where an attacker simply tries a large number of emails and
# passwords to see if any credentials match.
#
# Another common method of attack is to use a swarm of computers with
# different IPs to try brute-forcing a password for a specific account.
# Throttle POST requests to /login by IP address
#
# Key: "rack::attack:#{Time.now.to_i/:period}:logins/ip:#{req.ip}"
throttle('logins/ip', limit: 5, period: 20.seconds) do |req|
if req.path == '/users/sign_in' && req.post?
req.ip
end
end
Thoughts?