Server-Side Request Forgery attacks involve getting a target server to perform requests on our behalf. Rather than covering some great material already published, this post will be to introduce a new PHP package designed to help prevent these sort of attacks.
To protect our scripts from being abused in this way, we simply validate any URL or file path being passed to functions which can send requests. Of course, this is easier said than done.
The first step is to validate the provided scheme (and port if specified). This is to stop requests to PHP’s extra protocols (
phar://) which would let an attacker read files off of the file system.
The second is to validate the URL itself. This is to make sure that someone isn’t requested a blacklisted domain (such as
https://jira.fin1te.net), or a private/loopback IP (such as
127.0.0.1). You should also resolve any domain names to their IP addresses, and validate these to make sure someone doesn’t use a DNS entry pointing to an invalid IP.
Lastly, any redirects which cURL would normally handle should be caught, and the URL specified in the
Location header validated using the above steps.
Putting this all together, we get SafeCurl.
SafeCurl has been designed to be a drop in replacement for the
curl_exec function in PHP. Whilst there are other functions in PHP which can be used to grab the contents of a URL (
curl_exec is the most popular. In future versions, support for other functions will be added.
To use SafeCurl, simply call the
SafeCurl::execute method where you’d usually call
curl_exec, wrapping everything in a
By default, SafeCurl will only allow HTTP or HTTPS requests, to ports 80, 443 and 8080, which don’t resolve to a private/loopback IP address.
If you manage to find a way of bypassing it completely, then please participate in the bounty.
Bounty (Capture the Bitcoins)
In order to give SafeCurl a real-world test, I’ve hosted a demo site, which lets you try out the different protections.
The document root contains a Bitcoin private key, with 0.25BTC contained within. This file is only accessible from localhost, so if you do bypass it, grab the file and the Bitcoins are yours.
The source code for the site is also available, if you’re interested.
For more information see the Bounty page.