Server Side Request Forgery (SSRF) is a type of attack that can be carried out to compromise a server. The exploitation of a SSRF vulnerability enables attackers to send requests made by the web application, often targeting internal systems behind a firewall.
Sometimes a server needs to make URL-request based on user input. A clear example would be an import-function, where you can import images from a URL, perhaps when setting a profile picture. When you as a user enter a URL, the server will make a request to that URL and fetch the image.
Interesting things happen when this function can be used to make request to internal services, for example, local IP-addresses (RFC1918) which are not publicly accessible from the internet.
If the URL given by the user is not an image, the error page will often show the response of the requested URL. That makes it easier to exploit, but is not a requirement. You can no longer request information from internal systems, but can still make internal API-calls.
Imagine the following PHP code:
$content = file_get_contents($_GET['url']);
The above code will fetch data from a URL using PHP’s file_get_contents() function and then save it to the disk. A legitime request would then look like:
And the web application would make a request to https://website.com/images/cat.jpg.
This code could be exploited with SSRF. Such an attack could look something like:
In this case the vulnerable web application would make a GET request to the internal REST API service, trying to access the /api/v1/getuser/id/1 endpoint. This REST API service is only accessible on the local network, but due to a SSRF vulnerability it was possible for the attacker to make such an internal request and read that response.
Sometimes you can make a request to an external server, and the request itself may contain sensitive headers. One of many examples would be HTTP basic passwords, if a proxy has been used. SSRF can therefore be carried out to both internal and external services.
The vulnerability often occurs when you are supposed to be able to make requests to a certain domain, but are able to bypass the parser/filter. A security researcher known as Orange Tsai spoke about this previously at Black Hat 2017.
Not to be forgotten, sometimes it is possible to use other schemes and protocols in a SSRF attack other than HTTP. Examples of these are file://, phar://, gopher://, data://and dict://
It is common to have a proper firewall/routing rules for external applications, but normally nothing inside the network. That means that an attacker is able to make a device already on the network send the requests, there are no security restrictions to care about for internal systems.
Due to microservices and serverless platforms, SSRF will probably be a bigger thing in the future. Making internal requests now means that you can interact with other parts of the service, pretending to be the actual service.
If you are using a service such as AWS or Google Cloud, it is often possible to request sensitive tokens/credentials through some API.
Metadata in AWS, Google Cloud, and others: https://gist.github.com/jhaddix/78cece26c91c6263653f31ba453e273b
There is no universal protection against SSRF attacks, however there are a few things to have in mind:
- A blacklist is not a good protection because with so many different protocols, schemes, encodings and super complex URI syntax, bypasses will most certainly occur. Because of this, a whitelist is a better approach.
- When developing REST API’s, it is better to accept other HTTP verbs than POST and GET which will make it harder for a SSRF vulnerability to make correct requests to the API service. If a SSRF vulnerability is only able to make internal GET requests it won’t be able to speak with the API. It is also important to validate both the request and response to internal services.
- Services such as Kibana, Redis, Elasticsearch, MongoDB and Memcached do not per default require authentication, and adding that to those services may make it harder to exploit a SSRF vulnerability.
The most common way for Detectify to detect this kind of vulnerability is by using Out-of-Band-Exploitation. For each test we generate a unique string, which we then try to send a request to as part of the domain name.
For a specific test we might generate foobar. We then make a request to the server including foobar.poem.detectify.com. If the nameserver for that subdomain then get a lookup-request for foobar we know that the server has tried to send a request to it, even if we were unable to read the response. For specific tests we may have other solutions in place.
Detectify is automated web application scanner checking for 1000+ known vulnerabilities including OWASP Top 10 and SSRF. Start your Detectify free trial today to see whether your applications are vulnerability to SSRF and more.