Skip to content

Instantly share code, notes, and snippets.

@cannikin
Created November 10, 2015 17:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cannikin/1dba5bdb62d1497b3d32 to your computer and use it in GitHub Desktop.
Save cannikin/1dba5bdb62d1497b3d32 to your computer and use it in GitHub Desktop.
Rails code for raising ActionDispatch::RemoteIp::IpSpoofAttackError
# Determines originating IP address. REMOTE_ADDR is the standard
# but will be wrong if the user is behind a proxy. Proxies will set
# HTTP_CLIENT_IP and/or HTTP_X_FORWARDED_FOR, so we prioritize those.
# HTTP_X_FORWARDED_FOR may be a comma-delimited list in the case of
# multiple chained proxies. The last address which is not a known proxy
# will be the originating IP.
def calculate_ip
client_ip = @env['HTTP_CLIENT_IP']
forwarded_ips = ips_from('HTTP_X_FORWARDED_FOR')
remote_addrs = ips_from('REMOTE_ADDR')
check_ip = client_ip && forwarded_ips.present? && @middleware.check_ip
if check_ip && !forwarded_ips.include?(client_ip)
# We don't know which came from the proxy, and which from the user
raise IpSpoofAttackError, "IP spoofing attack?!" \
"HTTP_CLIENT_IP=#{@env['HTTP_CLIENT_IP'].inspect}" \
"HTTP_X_FORWARDED_FOR=#{@env['HTTP_X_FORWARDED_FOR'].inspect}"
end
not_proxy = client_ip || forwarded_ips.last || remote_addrs.first
# Return first REMOTE_ADDR if there are no other options
not_proxy || ips_from('REMOTE_ADDR', :allow_proxies).first
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment