Server-side request forgery (SSRF) is the only type of vulnerability that has its own category in the OWASP Top 10 2021 list. Several major cybersecurity breaches in recent years, including Capital One and MS Exchange attacks, involved the use of SSRF as one of the break-in techniques.
SSRF vulnerabilities let an attacker send crafted requests from the back-end server of a vulnerable application. Criminals usually use SSRF attacks to target internal systems that are behind firewalls and are not accessible from the external network. An attacker may also leverage SSRF to access services available through the loopback interface (127.0.0.1) of the exploited server.
SSRF vulnerabilities occur when an attacker has full or partial control of the request sent by the web application. A common example is when an attacker can control the third-party service URL to which the web application makes a request.
The following is an example in PHP that is vulnerable to server-side request forgery (SSRF).
<?php
/**
* Check if the 'url' GET variable is set
* Example - http://localhost/?url=http://testphp.vulnweb.com/images/logo.gif
*/
if (isset($_GET['url'])){
$url = $_GET['url'];
/**
* Send a request vulnerable to SSRF since
* no validation is being done on $url
* before sending the request
*/
$image = fopen($url, 'rb');
/**
* Send the correct response headers
*/
header("Content-Type: image/png");
/**
* Dump the contents of the image
*/
fpassthru($image);}
In the above example, the attacker has full control of the url parameter. They can make arbitrary GET requests to any website on the Internet and to resources on the server (localhost).
In the following example, an attacker makes a request to Apache HTTP servers with mod_status enabled (enabled by default).
GET /?url=http://localhost/server-status HTTP/1.1
Host: example.com
Attackers can also use SSRF to make requests to other internal resources that the web server has access to, which are not publicly available. For example, they can access cloud service instance metadata like AWS /Amazon EC2 and OpenStack. An attacker can even get creative with SSRF and run port scans on internal IPs.
GET /?url=http://169.254.169.254/latest/meta-data/ HTTP/1.1
Host: example.com
Apart from the http: // and https: // URL schemas, an attacker may take advantage of lesser-known or legacy URL schemas to access files on the local system or on the internal network.
The following example uses the file: /// URL schema.
GET /?url=file:///etc/passwd HTTP/1.1
Host: example.com
Some applications may enable attackers to use more exotic URL schemas. For example, if the application uses cURL to make requests, the 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
Host: example.com
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 Memcached, which is not normally exposed.
Note that SSRF exploits often allow attackers to follow up with other dangerous techniques. As an example, you can escalate blind SSRF to remote code execution (RCE).
Detecting server-side request forgery
To automatically detect server-side request forgery, you need to rely on an intermediary service. Detection of such vulnerabilities requires an out-of-band and time-delay vector. Acunetix solves this by using AcuMonitor as the intermediary service.
During a scan, Acunetix makes requests that contain a unique AcuMonitor URL. If AcuMonitor receives a request on one of these unique URLs, it sends a notification back to Acunetix. It causes Acunetix to raise an alert for SSRF.
The following is a result of an Acunetix scan with AcuMonitor, which detected a server-side request forgery. The alert contains information about the HTTP request. It includes the IP address of the server that made the request and the User-Agent
string used in the request (if any). This information can help developers identify the source of the problem and fix it.
Mitigating server-side request forgery
Simple blacklists and regular expressions applied to user input are a bad approach to mitigating SSRF. In general, blacklists are a poor means of security control. Attackers will always find methods to bypass them. In this case, an attacker can use an HTTP redirect, a wildcard DNS service such as xip.io, or even alternate IP encoding.
Whitelists and DNS resolution
The most robust way to avoid server-side request forgery (SSRF) is to whitelist the hostname (DNS name) or IP address that your application needs to access. If a whitelist approach does not suit you and you must rely on a blacklist, it’s important to validate user input properly. For example, do not allow requests to endpoints with private (non-routineable) IP addresses (detailed in RFC 1918).
However, in the case of a blacklist, the correct mitigation to adopt will vary from application to application. In other words, there is no universal fix to SSRF because it highly depends on application functionality and business requirements.
Response handling
To prevent response data from leaking to the attacker, you must ensure that the received response is as expected. Under no circumstances should the raw response body from the request sent by the server be delivered to the client.
Disable unused URL schemas
If your application only uses HTTP or HTTPS to make requests, allow only these URL schemas. If you disable unused 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: //.
Authentication on internal services
By default, services such as Memcached, Redis, Elasticsearch, and MongoDB do not require authentication. An attacker can use server-side request forgery vulnerabilities to access some of these services without any authentication. Therefore, to protect your sensitive information and ensure web application security, it’s best to enable authentication wherever possible, even for services on the local network.
Frequently asked questions
To avoid SSRF, never trust user input. If your application needs to pass URLs in requests, use a whitelist for IP addresses and domains, and always validate if the response has the expected format and content.
Read more about general secure programming habits.
Get the latest content on web security
in your inbox each week.