I’ve recently bumped into an interesting post about a stackoverflow vulnerability discovered by Anthony Ferrara. I didn’t think too much about it. I’ve come across similar issues before, where the application relies on a piece of information that might be easy to forge. Telephony systems are vulnerable to Caller ID spoofing, which becomes increasingly easier with Voice-Over-IP providers. Web based applications can also be fooled if they rely on header information, such as the X-Forwarded-For, typically used by Proxy servers.
I was experimenting with switching rails from Phusion Passenger to Unicorn, when I suddenly came across a strange error message:
ActionDispatch::RemoteIp::IpSpoofAttackError (IP spoofing attack?!HTTP_CLIENT_IP="192.168.0.131"HTTP_X_FORWARDED_FOR="192.168.0.131"): app/controllers/application_controller.rb:138:in `append_info_to_payload'
That looked quite impressive. Rails is trying to identify spoofing attacks and raise an exception when it happens? Nice.
However, after digging a little deeper, trying to figure out what’s actually happening, it seems that Rails might actually be vulnerable to spoofing attacks under certain setups. I will try to describe those scenarios and suggest a few workarounds to avoid any pitfalls.
What I observed applies to Rails latest stable (3.2.9 at the time of writing), previous versions and potentially future versions as well (including 4.0).
Your rails application might be vulnerable to IP spoofing. To test it, try to add a fake
X-Forwarded-For header and check which IP address appears in your log files.
curl -H "X-Forwarded-For: 18.104.22.168" http://your.website.com
You can try to implement one of the workarounds mentioned below.