A little tip for people trying to armor themselves against this problem: If your app reaches out to do network transactions, it really ought to block localhost. However, bear in mind that localhost isn't "127.0.0.1"... it's "127.0.0.0/8" (or "127.x.x.x" if you don't casually speak CIDR). Ping 127.2.88.33 on your console now... you'll see replies.
On the flip side, if you're doing a security test like this, I've gotten mileage out of convincing apps to access local resources with things like 127.88.23.245, precisely because the developer blocked 127.0.0.1 specifically and thought they were done.
You should also usually block all internal and external IPs for your entire network, but especially in the cloud this can begin to get tricky. Still, you should.
Also worth noting: don't just regex-check the URL with (localhost|127.*) or something similar. Any hostname could point to 127.0.0.1.
iptables with --uid-owner denying traffic to local/private IP space (plus infrastructure-specific stuff like EC2's instance metadata service) would probably be the best option.
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# Create a chain for outgoing proxy traffic
-N PROXY_OUT
-A OUTPUT -m owner --uid-owner proxy -j PROXY_OUT
# Allow replies to the requestor
-A PROXY_OUT -p tcp --sport 8080 -j ACCEPT
# Prevent proxy from talking to anything non HTTP{,s} (and DNS)
-A PROXY_OUT -p tcp -m multiport ! --dports 80,443,53 -j DROP
# Allow DNS udp
-A PROXY_OUT -p udp --dport 53 -j ACCEPT
# Allow the proxy to specific private ips (demos servers)
-A PROXY_OUT -d xxx.xxx.xxx.xxx/32 -j ACCEPT
# Prevent proxy from talking to anything private
-A PROXY_OUT ! -o <%= @public_iface %> -j DROP
-A PROXY_OUT -d 10.0.0.0/8 -j DROP
-A PROXY_OUT -d 172.16.0.0/12 -j DROP
-A PROXY_OUT -d 192.168.0.0/16 -j DROP
# Prevent proxy from talking to services via public ips
<% @aws_public_ips.each do |name, facts| %>
# <%= name %>
-A PROXY_OUT -d <%= facts['ec2_public_ipv4'] %>/32 -j DROP
<% end %>
Anything I missed? Blocking outgoing ports is to taste.
That seems to cover everything in IPv4, but if you have IPv6 enabled, you probably want fd00::/8, fe80::/10 and ::1/128 as well (disclaimer: my knowledge of IPv6 is rather limited.)
that is how I got around all the internet filters in our high school. nothing makes you feel more like a hacker than punching some numbers on a calculator while all your friends watch, and bam, you're browsing forbidden websites while they all say "whoaa!"
localhost.fbi.gov is a great example. (Also a great way to exfiltrate fbi.gov cookies on a multi-user system, but that's another discussion completely.)
Great point. Also, possibly all reserved IPv4 spaces (see the Apache proxy mentioned in the article), not just 127/localhost (and don't forget 169.254/16 as the article points out). It's hard to do this right, since there might be use cases where local networks should be allowed, but better to err on the side of caution.
This seems a little like playing whack-a-mole security. Is there a comprehensive list of what should be blocked by default unless your specifically needs it?
If you run an open proxy, then you're choosing to give away any privileges you've received on the basis of your network position or IP. By default, one should avoid running open proxies.
They should have run the proxy on a host that they didn't give any special IP-based privileges to. The other nodes shouldn't honor X-Forwarded-For headers from the IP hosting the proxy.
The next big mistake is configuring your packet filters and application ACLs to only filter requests coming in from the internet; they can still make requests to 54.175.131.207 or whatever the IP is and the source of the request packets will be from the loopback interface.
And the IPv6 equivalent is "::1". Did they even set up basic packet filtering or ACLs for IPv6 requests? If they have no public IPv6 address, they probably never did.
Quick question. Is this a field that layman web developers/script developers should know? Or is this more of the domain of information security/network security? I don't make apps as a product, but I do like to tinker with stuff and make projects that sometimes my friends use. Not really sure what counts as a network transaction.
> Ping 127.2.88.33 on your console now... you'll see replies.
People's results here might vary depending on their operating system. For me, these pings were returned on a vagrant box running ubuntu, but dropped (not blocked) on the host system.
I don't think this is true on Windows. The hostname is tied to the IP which is tied to the loopback adapter and it defaults to the IPv6 addr anyway. The hosts file has it commented out as the literal 127.0.0.1 for those who need it on IPv4.
On the flip side, if you're doing a security test like this, I've gotten mileage out of convincing apps to access local resources with things like 127.88.23.245, precisely because the developer blocked 127.0.0.1 specifically and thought they were done.
You should also usually block all internal and external IPs for your entire network, but especially in the cloud this can begin to get tricky. Still, you should.
And don't forget IPv6.