Server-side request forgery (SSRF)

What is SSRF?

Server-side request forgery (SSRF) is a cybersecurity term for a specific class of software security vulnerabilities. If a malicious hacker is able to send a request from the back-end of the software to another server or to a local service, the software has a server-side request forgery vulnerability.

Severity:⬛⬛⬛⬛⬜severe
Prevalence:⬛⬛⬜⬜⬜discovered regularly
Scope:⬛⬛⬛⬛⬜may appear in all networked software
Technical impact:access to privileged resources
Worst-case consequences:full system compromise
Quick fix:sanitize user data in calls to other servers

How does server-side request forgery work?

When you build networked software, you often need to make requests to other servers. Developers typically use them to fetch remote resources, such as software updates, or to import metadata from another application. Such requests are not dangerous in general, but if implemented incorrectly, they can make the software vulnerable to server-side request forgery.

An SSRF vulnerability can be introduced when you use user input data to create a request, for example, when building a URL. To perform an SSRF attack, an attacker can then change a parameter value in the vulnerable software to create or control requests coming from that software and going to other servers or even the same server.

SSRF vulnerabilities may appear in any type of computer software, in almost every programming language, and on any platform, as long as the software works in a networked environment. Most SSRF vulnerabilities happen in web applications and other networked applications, but they may also appear in server software itself.

In addition to regular (non-blind) SSRF vulnerabilities, there are also other types of SSRF. These include blind SSRF vulnerabilities, where the attacker does not directly receive any data from the attacked resource. Attackers can use blind SSRF to trigger actions that they can only trigger from within an internal network.

SSRF is classified as CWE-918. Also note that due to its severity, SSRF is the only type of vulnerability that has its own category in the OWASP Top 10 2021 list. 

Example of a web application SSRF attack

The most common example of SSRF in web applications is when the attacker can input or influence a third-party service URL to which the web application makes a request.

Vulnerable code

The following code was written to output a PNG image imported from another URL as if it was part of your own HTML page.

<?php
  if (isset($_GET['url'])) {
    $url = $_GET['url'];
    $image = fopen($url, 'rb');
    header("Content-Type: image/png");
    fpassthru($image);
  }
?>

Note that the attacker has full control of the url parameter. They can make arbitrary GET requests to any external IP, including those on the local network, and to resources on the server that hosts the vulnerable application (localhost).

The attack vector

Using the vulnerable application, the attacker can make the following request to Apache web servers with mod_status enabled (which is the default configuration):

GET /?url=http://localhost/server-status HTTP/1.1

As a result, the attacker receives detailed information on the server version, installed modules, and more. This helps the attacker search for more potential vulnerabilities.

Apart from the http and https URL schemas, attackers might also use legacy URL schemas in their payloads, such as the file schema, to try and access files on the local system or the internal network.

GET /?url=file:///etc/passwd HTTP/1.1

This payload will provide the attacker with the content of the /etc/passwd file from the server hosting the vulnerable application.

Some applications might permit attackers to use exotic URL schemas. For example, if the application uses cURL to make requests, an attacker can use the dict URL schema to make requests to any host on any port and send custom data.

GET /?url=dict://localhost:11211/stat HTTP/1.1

The above request will cause the application to connect to localhost on port 11211 and send the string stat. Port 11211 is the default port used by the Memcached caching service. This port is not normally exposed to the outside network, but it is accessible from localhost, in this case via SSRF.

Potential consequences of an SSRF attack

There are two primary goals that an attacker has in mind when attempting a server-side request forgery attack:

  • Access to privileged resources: Malicious hackers usually use SSRF attacks to target internal resources with private IP addresses or located behind firewalls, or to access services available through the loopback interface (http://127.0.0.1) of the exploited server. This could include, for example, Azure/AWS cloud service metadata (http://169.254.169.254), internal APIs, and in some cases even privileged files on the vulnerable server. Attackers may even use SSRF for local port scanning.
  • Hiding the real source of the connection: For example, an attacker may use SSRF even if they have direct access to the resource, just to cover their tracks. This way, access attempts appear to originate from the back-end of the local application that is vulnerable to SSRF, not directly from the attacker, which makes forensics more troublesome. The attacker might also use your vulnerable server to attack someone else, making it appear that your systems were the source of the actual attack.

For these reasons, SSRF exploits are usually a preliminary attack step before exploiting another vulnerability. For example:

  • The attacker may first perform SSRF to gain access to a business-critical application located on another server, which can only be accessed from the internal network, and then use SQLi to gain access to the database behind that business application.
  • The attacker may also use SSRF to gain access to a local application installed on the server hosting an application with a remote code execution (RCE) vulnerability, then use that application to gain full shell access, and then exploit an operating system vulnerability to get root access to the server.

Therefore, in the worst case, if SSRF is combined with other attack vectors such as RCE, XXE, XSS, CSRF, or SQLi, it may allow attackers to take full control of a vulnerable server or access highly sensitive data.

Examples of known SSRF vulnerabilities

  • The 2019 Capital One breach. Paige Thompson acquired AWS access keys by exploiting SSRF to access the AWS EC2 metadata service. Thanks to these keys, Thompson was able to list and sync the S3 buckets to a local disk, and therefore gained access to all the data contained in them.
  • The 2021 Microsoft Exchange attacks. The Hafnium group exploited the CVE-2021-26855 SSRF vulnerability, which allowed them to first authenticate as an Exchange server and then escalate the attacks.

How to detect SSRF vulnerabilities?

The best way to detect SSRF vulnerabilities depends on whether they are already known or unknown.

  • If you only use commercial or open-source software and do not develop software of your own, you may find it enough to identify the exact version of the system or application that you are using. If the identified version is vulnerable to SSRF, you can assume that you are susceptible to that SSRF vulnerability. You can identify the version manually or use a suitable security tool, for example, software composition analysis (SCA) software in the case of web applications or a network scanner in the case of networked systems and applications.
  • If you develop your own software or want to potentially find unknown SSRF vulnerabilities (zero-days) in known applications, you must be able to successfully exploit the SSRF vulnerability to be certain that it exists. In such cases, you must either perform manual penetration testing with the help of security researchers or penetration testers or use a security testing tool that can automatically exploit vulnerabilities (which is possible for web security testing only). Examples of such tools are Invicti and Acunetix by Invicti. We recommend using this method even for known vulnerabilities.

When dealing with custom software, note that server-side request forgery vulnerabilities are not easy to detect using simple tools because finding them requires a combined approach. You may identify some SSRF vulnerabilities that involve access to other servers simply based on being able to access these servers. This is the way that many SSRF vulnerabilities are detected by Acunetix and Netsparker. Both these tools include an external listener service and whenever a scan causes your application to send an HTTP request to that service, you have proof of an SSRF vulnerability.

However, in the case of SSRF attacks that target the web application server itself or internal services only, such a third-party service is not sufficient. In such cases, you must check if it is possible to access typical local resources, such as publicly accessible files that you know exist on the server. This can also be automated with professional tools, but additional penetration testing is always recommended to detect less common cases.

How to prevent SSRF vulnerabilities in web applications?

The only way to guarantee that your code will not have an SSRF vulnerability is not to use any data originating from user input when you access other servers. Unfortunately, many applications need such functionality and in these cases, you need to explore less-than-perfect solutions instead. As with most other software vulnerabilities, these solutions mostly rely on input validation and sanitization. However, remember that there is no universal method because the available options highly depend on application functionality and business requirements.

Avoid using blacklists or regular expressions to filter user input. There is always a risk that attackers will find methods to bypass them. In the case of SSRF, an attacker can use an HTTP redirect, a wildcard DNS service such as xip.io, or even alternate IP encoding. If you absolutely must rely on a blacklist, make sure you validate user input properly. For example, do not allow requests to endpoints with private (non-routable) IP addresses (RFC 1918).

Preventing SSRF requires a combined approach

The following combined methods will help you avoid most SSRF vulnerabilities, but you must realize that they are not perfect, even when all used together. That is why security testing is needed even with the best secure coding practices.

  • Whitelisting: You should whitelist the hostnames (DNS names) or IP addresses that your application needs to access. However, this method alone will not prevent attackers from, for example, running port scanning on the whitelisted server or accessing other resources on that server.
  • Response handling: If your application displays or processes data received from other servers, you must ensure that the response you received is in an expected format. You should never send the raw response body to the client. However, this does not protect against blind SSRF attacks.
  • Schema control: If your application only uses HTTP or HTTPS to make requests, allow only these URL schemas. If you disable all other URL schemas, the attacker will be unable to use the web application to make requests using potentially dangerous schemas such as file, dict, ftp, and gopher.

How to mitigate SSRF attacks?

Methods to mitigate SSRF attacks are different depending on the type of software that has these vulnerabilities.

  • In the case of custom software, such as web applications, the only way to permanently mitigate the SSRF is to avoid including user input in any calls made to other servers. All other methods are imperfect and require a custom combined approach depending on the application.
  • In the case of known SSRFs in third-party software, you must check the latest security advisories for a fix and update to a non-vulnerable version (usually the latest version).

In the case of zero-day SSRF in third-party software, you can only rely on temporary WAF (web application firewall) rules for mitigation. However, this only makes the SSRF harder to exploit and does not eliminate the root cause.

Protecting potential targets

Mitigating SSRF requires focusing not only on the potentially vulnerable application but also on the possible targets of an SSRF attack. This includes making sure that even if you have an SSRF vulnerability somewhere in your internal network, local services on the network cannot be abused through that SSRF.

For example, services such as Memcached, Redis, Elasticsearch, and MongoDB do not require authentication by default because they usually run on internal networks. If you don’t turn on authentication, attackers may be able to access these services via server-side request forgery vulnerabilities in other applications.

Therefore, to protect your sensitive information and ensure web application security, you should enable authentication wherever possible to minimize the risk of SSRF attacks on local services.

ClassificationID
CAPEC347
CWE918
WASC15
OWASP 2021A10 (standalone category)

Related blog posts