The Server Side Request Forgery Vulnerability and How to Prevent It
Learn how to protect your web application from SSRF vulnerabilities by learning what exactly they are and how bad actors can use them to target your system.
Join the DZone community and get the full member experience.Join For Free
Web applications can trigger inter-server requests, which are typically used to fetch remote resources, such as software updates, or to import data from a URL or other web applications. While such inter-server requests are typically safe, unless implemented correctly, they can render the server vulnerable to Server Side Request Forgery.
Introduction to Server Side Request Forgery
A Server Side Request Forgery (SSRF) vulnerability allows an attacker to change a parameter used on the web application to create or control requests from the vulnerable server.
When information in a web application has to be retrieved from an external resource, such as an RSS feed from another website, server-side requests are used to fetch the resource and include it in the web application. For example, a developer can use a URL such as
https://example.com/feed.php?url=externalsite.com/feed/ to retrieve the remote feed. If the attacker is able to change the URL parameter to localhost, then he is able to view local resources hosted on the server, making it vulnerable to Server Side Request Forgery.
If an attacker is able to control the destination of the server side requests they can potentially perform the following actions:
- Abuse the trust relationship between the vulnerable server and others.
- Bypass IP whitelisting.
- Bypass host-based authentication services.
- Read resources which are not accessible to the public, such as trace.axd in ASP.NET or metadata APIs in an AWS environment.
- Scan the internal network to which the server is connected.
- Read files from the web server.
- View Status Pages and interact with APIs as the web server.
- Retrieve sensitive information such as the IP address of a web server behind a reverse proxy.
Typical Exploitation of a Server Side Request Forgery Vulnerability
Since the attacker cannot send direct requests to the victim's server because they are blocked by a firewall, to scan an internal network the attacker has to:
- Send a request to the vulnerable web server that abuses the SSRF vulnerability.
- The web server makes a request to the victim's server which sits behind the firewall.
- The victim's server responds with the data.
- If the specific SSRF vulnerability permits it, the data is sent back to the attacker.
Repercussions of a Server Side Request Forgery Vulnerability
1. Abusing the Trust Relationship to the Affected Server
As a best practice, it is always good to keep the attack surface as small as possible, therefore access to certain ports or actions is often restricted to whitelisted machines only. In fact, servers usually have a trust relationship with other machines in order to easily share data and allow administrative tasks.
For example at a network level, this trust means a firewall only allows access to certain ports if the machine requesting access is on the same local network, or if its IP address is explicitly trusted.
At a software level, trust can be as follows: authentication is not required for some administrative tasks, as long as the IP is 127.0.0.1 or it is inside the internal network. Such trust can also be used as an additional security measure, to assure that even if an attacker knows the password, he cannot log in without access to the local network.
By exploiting an SSRF vulnerability, an attacker can circumvent the above restrictions and, for example, query other servers that trust the affected machine, or craft malicious requests to interact with certain ports that aren't accessible from the outside network. The attacker can, therefore, perform malicious actions on the server itself that would otherwise not be possible from the outside.
2. Scan Local or External Networks
By exploiting a Server Side Request Forgery vulnerability, attackers may be able to scan the local or external networks to which the vulnerable server is connected. Attackers typically use the time a page takes to load, error message, or banners of the service they are probing to determine whether the probe they are targeting is responding or not and to confirm if the tested port is open.
Example of How to Scan a Network via an Exploited SSRF Vulnerability
Imagine a service on a website that allows you to fetch remote jpeg images so it can determine their dimensions.
As a precaution, the service checks if there is a Content-Type header with the value "image/jpeg" in the response from the remote source. If there isn't, or if the content type is different, it returns the error "Please provide jpeg images only," since it assumes that the provided file is not a jpeg. If instead there is a problem connecting to the remote source, the service returns the error, "No image found!"
Let's see how attackers can use different inputs that affect the response of the service to determine if a host is up or not:
If we request
https://victim.com/image.php?url=https://example.com/picture.jpg we get the height and width of the image, meaning that this is a valid picture with a correct Content-Type header.
Now let's try a different request and feed the server with an HTML file rather than an image;
https://victim.com/image.php?url=https://example.com/index.html. In such cases, the response from the service is "Please provide jpeg images only," since the page loaded has the wrong Content-Type header, which is text/html.
Now let's request an invalid URL;
https://victim.com/image.php?url=https://example.invalid/. The service returns the error "Image not found," meaning that there was an error fetching the remote resource.
Now that we know how the application behaves for different inputs we can try to abuse it. We know that a valid URL with a wrong or missing Content-Type header returns the error, "Please provide jpeg images only." That means that if we send the following request,
https://victim.com/image.php?url=127.0.0.1:3306, and we get the error, "Image not found," then it means there is no response on 127.0.0.1 port 3306. If we get the error "Please provide jpeg images only," it means that there is a response from the server, thus a service is running on that port. Therefore we can use this method to probe different internal IP addresses and ports to make a complete scan.
3. Read Files From the Server
When the content of a remote resource is directly rendered to a page, there is a possibility that the attackers read the content of the files. As an example, consider a web service that removes all images from a given URL and formats the text. It works by first getting the response body of a given URL, then applies the formatting.
If we use the file:// URI instead of http:// or https:// we are able to read files from the local file system. For example, if we use the URI file:///etc/passwd we could print the content of the passwd file on Unix systems to the page. The same technique can be used to view the source code of the vulnerable web application.
Impacts of Server Side Request Forgery
As seen in the above examples, the impact of exploiting a Server Side Request Forgery vulnerability is almost always information disclosure, such as:
- It is possible to scan ports and IP addresses.
- Interact with some protocols such as Gopher, which allow you to make further discoveries.
- Discover the IP addresses of servers running behind a reverse proxy.
- Remote code execution.
There are several other things attackers can do when exploiting an SSRF vulnerability, some of which can have more severe consequences, but it mainly depends on how the web application uses the responses from the remote resource.
Preventing Server Side Request Forgery (SSRF)
To prevent SSRF vulnerabilities in your web applications, it is strongly advised to use a whitelist of allowed domains and protocols from where the web server can fetch remote resources.
Also, as a rule of thumb, you should avoid using user input directly in functions that can make requests on behalf of the server. You should also sanitize and filter user input, but it is typically very hard to implement mainly because it is virtually impossible to cover all the different scenarios.
An attacker can:
- Use encoded IP addresses which will be translated to an IP in an internal network.
- 1 -> same as localhost
- 123.123.123 -> same as localhost
- Supply hostnames that resolve to internal IP addresses.
- Bypass host blacklisting by applying dots at the end of the hostname.
This is only a small portion of bypasses that attackers have in their arsenal, therefore it is recommended to avoid user input in functions that issue requests on behalf of the server.
Published at DZone with permission of Sven Morgenroth, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.