Server-side request forgery (SSRF) is an attack that allows attackers to send malicious requests to other systems via a vulnerable web server. Listed in the OWASP Top 10 as a major application security risk, SSRF vulnerabilities can lead to information exposure and open the way for far more dangerous attacks. This post shows how SSRF works and how you can identify and prevent SSRF vulnerabilities in your web applications.
Web applications can trigger requests between HTTP servers. These are typically used to fetch remote resources, such as software updates, or to import metadata from a URL or another web application. Such inter-server requests are not dangerous in general, but unless implemented correctly, they can make a server vulnerable to server-side request forgery, or SSRF.
A server-side request forgery (SSRF) vulnerability is introduced when user-controllable data is used to build the target URL. To perform an SSRF attack, an attacker can then change a parameter value in the vulnerable web application to create or control requests from the vulnerable server.
External resources accessed by a web application may include internal services, for example an RSS feed from another website. A developer might use the following URL to retrieve a remote feed:
https://example.com/feed.php?url=externalsite.com/feed/to
If the attacker is able to change the url
parameter to localhost
(the loopback interface), this may allow them to view local resources hosted on the server, making it vulnerable to server-side request forgery.
If attackers can control the destination of server-side requests, this opens up a whole array of offensive activities, potentially allowing them to:
trace.axd
in ASP.NETServer-side request forgery is a well-known vulnerability and a regular item on the Open Web Application Security Project’s list of top ten web application security risks. In the OWASP Top 10 for 2021, it has even (for the first time) received its own category as A10:2021 – Server-Side Request Forgery (SSRF). It was included as a separate category based on the results of a community survey.
As modern web applications get more complex and interconnected, fetching a URI has become a fundamental operation for delivering content and functionality. With the rise in server-side requests, SSRF vulnerabilities have also become more common. At the same time, their scope and impact are expanding due to the growing prevalence of cloud services and intricate cloud-based application architectures, which can allow attackers to access web infrastructures and cloud data sources via a compromised server.
In a typical SSRF scenario, an external attacker who wants to access an internal server can’t use direct requests because they would be blocked by the firewall. Instead, malicious actors can exploit an SSRF vulnerability to make their attack via a vulnerable web server:
While many web vulnerabilities directly affect the target system, SSRF allows attackers to use the target as an intermediary that passes requests to a third system. So while an SSRF attack might not be damaging in itself, it can provide malicious hackers with access to internal systems that were never supposed to be accessible from the Internet. There are several reasons why this is dangerous.
As a security best practice, you should always keep your attack surface as small as possible on all levels. In internal networks, this usually means that access to certain ports or actions is restricted to specific whitelisted machines only. To maintain security while still being able to exchange data and perform administrative tasks, servers often have a trust relationship with select other machines.
At a network level, this trust can mean that a firewall only allows access to certain ports if the requesting machine is on the same local network or if its IP address is explicitly trusted. At a software level, you can have implicit trust in local machines so that authentication is not required for some administrative tasks as long as the IP is 127.0.0.1 or perhaps inside the internal network. This adds some degree of physical security because even if an attacker obtains valid credentials, they can’t log in without access to the local network.
By exploiting an SSRF vulnerability, an attacker can circumvent such restrictions to interact with other servers that trust the affected machine. This could mean sending data queries or crafting malicious requests to interact with ports that aren’t accessible from the outside network. By forging server-side requests, an external attacker can perform malicious actions on the target server that would otherwise not be possible from the outside.
By exploiting a server-side request forgery vulnerability, attackers may be able to scan local or external networks that the vulnerable server is connected to. While it is usually not possible to extract data directly, attackers can use the page load time, error messages, or banners of the service they are probing to indirectly determine whether the targeted service is responding or a tested port is open.
Imagine you have a website with a service that allows you to fetch JPEG images from a remote source so it can determine their dimensions. As a security control, the service checks if the response received from the remote source has a Content-Type
HTTP header with the value image/jpeg
. If the header is missing or specifies a different content type, the service assumes that a different image format was provided and returns the error message Please provide JPEG images only. If there is a problem connecting to the remote source, the service returns No image found!
Let’s see how attackers can use different inputs that affect the service response to determine if a host is up or not:
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.https://victim.com/image.php?url=https://example.com/index.html
. Now the service response is Please provide JPEG images only, since the supplied page has the wrong Content-Type
header (text/html
instead of image/jpeg
).https://victim.com/image.php?url=https://example.invalid/
. The service returns Image not found, meaning 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 missing or incorrect Content-Type
header returns the error Please provide jpeg images only. Let’s send the following request with an internal URL:
https://victim.com/image.php?url=127.0.0.1:3306
If we get the error Image not found, that means there is no response from host 127.0.0.1 on port 3306. However, if we get Please provide jpeg images only, it means that the internal server did respond, so there is a service running on that port. That way, we can use the vulnerable web application to probe different internal IP addresses and ports to make a complete scan. In effect, such an SSRF vulnerability allows attackers to perform port scanning without using an actual port scanner.
When the content of a remote resource is directly rendered to a page, there is a possibility that attackers could read file content. As an example, consider a web service that removes all images from a supplied URL and then nicely formats the text. To do this, it takes the response body for a given URL and then applies text formatting.
If the service is vulnerable to SSRF and allows us to supply a file://
URL instead of the usual http://
or https://
, we can use it to read files from the local file system. For example, if we use the URL file:///etc/passwd
on a UNIX-based system, we could display the content of the passwd file. The same technique can be used to view the source code of the vulnerable web application.
As seen in the above examples, the direct impact of exploiting a server-side request forgery vulnerability is nearly always information disclosure because attackers obtain a lot of useful information about systems and resources that should be inaccessible to them. However, the indirect consequences can be devastating, since SSRF can allow malicious actors to:
Because SSRF is primarily an access channel for further probes and attacks, there are also many other possibilities, depending on how the vulnerable web application uses responses received from the remote resource. Combined with other vulnerabilities in suitable conditions, SSRF can have severe consequences.
To prevent SSRF vulnerabilities in your web applications, you are strongly advised to use a whitelist of allowed domains and protocols for remote resources fetched by the web server. More generally, you should also avoid using user input directly in any functions that can make requests on behalf of the server. While it is always a good idea to sanitize and filter user input, you should not rely on this as your sole protection because it is virtually impossible to cover all the different scenarios.
Attackers can use a wide variety of tricks to bypass URL filtering:
This is only a small portion of bypasses that attackers have in their arsenal, so recommended practice is to avoid user input in functions that issue requests on behalf of the server.
Modern dynamic application security testing (DAST) solutions such as Invicti provide accurate vulnerability scanning for a wide variety of web vulnerabilities, including many server-side request forgery vulnerabilities. For out-of-band SSRF and other second-order vulnerabilities, Invicti uses a dedicated vulnerability testing infrastructure that allows it to identify and report security flaws that don’t return direct responses.
ClassificationID / SeverityPCI v3.26.5.6OWASP 2013A5OWASP 2017A6OWASP 2021A10 (standalone category)CWE918CAPEC347WASC15HIPAA164.306(a), 164.308(a)ISO27001A.14.2.5CVSS:3.0
CVSS:3.0: AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:N/A:N
Invicti Critical