What Is Server-Side Request Forgery (SSRF)?
SSRF attacks are no fun and need to be accounted for in any web-facing application. In this post we take a look at what they are and what you can do to help prevent them.
Join the DZone community and get the full member experience.Join For Free
Server-Side Request Forgery (SSRF) refers to an attack wherein an attacker is able to send a crafted request from a vulnerable web application. SSRF is usually used to target internal systems behind firewalls that are normally inaccessible to an attacker from the external network. Additionally, it’s also possible for an attacker to leverage SSRF to access services from the same server that is listening on the loopback interface (127.0.0.1).
Typically Server-Side Request Forgery (SSRF) occurs when a web application is making a request, where an attacker has full or partial control of the request that is being sent. A common example is when an attacker can control all or part of the URL to which the web application makes a request to some third-party service.
The following is an example in PHP that is vulnerable to Server-Side Request Forgery (SSRF).
* Check if the 'url' GET variable is set
* Example - http://localhost/?url=http://testphp.vulnweb.com/images/logo.gif
$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
* Dump the contents of the image
In the above example, since the attacker has full control of the URL parameter, in addition to being able to make arbitrary GET requests to any website on the Internet, an attacker can also make requests to resources on the server.
For example, it’s possible for an attacker to access services on localhost. In the following example, an attacker can make the following request on Apache HTTP Servers with
mod_status enabled (enabled by default).
GET /?url=http://localhost/server-status HTTP/1.1
Similarly, Server-Side Request Forgery (SSRF) can be used to make requests to other internal resources which the web server has access to, but are not publicly facing. Such an example would be accessing instance metadata in Amazon EC2 and OpenStack instances. This service is only available to the server and not to the outside world. An attacker can even get creative with SSRF and run port scans on internal networks with this approach.
GET /?url=http://169.254.169.254/latest/meta-data/ HTTP/1.1
Apart from the
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.
An example of such a request is the following using the
file:/// URL schema.
GET /?url=file:///etc/passwd HTTP/1.1
Depending on how the application is making the request, URL schemas other than file and HTTP could be available to the attacker to use. For example, if
cURL were being used to make requests (the example above makes use of
fopen() to make requests) it’s possible to 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 Memcached, which is not normally exposed. For a comprehensive list of attacks and URL schemas that can be used, ONSec Labs maintains a detailed document with a lot of useful information about Server-Side Request Forgery (SSRF) attacks.
Detecting Server-Side Request Forgery (SSRF)
In order to detect Server-Side Request Forgery (SSRF) automatically, we’ll need to rely on an intermediary service since the detection of such a vulnerability requires an out-of-band and time-delay vector. Acunetix solves this by making use of AcuMonitor as its intermediary service during an automated scan.
During a scan, Acunetix will make requests containing a unique AcuMonitor URL. If AcuMonitor receives a request on one of these unique URLs, it will send a notification back to Acunetix indicating it should raise an alert for Server-Side Request Forgery (SSRF).
The following is the result of an Acunetix scan with AcuMonitor to detect Server-Side Request Forgery (SSRF). The alert contains information about the HTTP request that was performed including the IP address of the server that made this request and the User-agent string used in the request if any were used. This information can help the developers identify the source of the problem and fix it.
Mitigating Server-Side Request Forgery (SSRF)
Whitelists and DNS Resolution
Implementing simple blacklists or regular expressions directly on the user’s input to filter out which IP addresses or domains can make requests is a bad approach to take when mitigating an SSRF.
In general, blacklists are a poor security control because there will always be bypasses not envisaged by a developer. In this case, bypass by an attacker is as easy as using an HTTP redirect, a wildcard DNS service such as xip.io, or even alternate IP encoding.
Instead, the most robust way of dealing with Server-Side Request Forgery (SSRF) is to whitelist the DNS name or IP address which your application needs access to. If a whitelist approach does not suit your use case, and you must rely on a blacklist, it’s important to validate user input properly. An example of this is to not allow requests to private (“non-routable”) 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 since it highly depends on the application’s functionality and business requirements.
Ensuring that the response received by the remote server is indeed what the server is expecting is important to prevent any unforeseen response data leaking to the attacker. Above all else, 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 makes use of HTTP or HTTPS to make requests, only allow those URL schemas. Disabling unused URL schemas will prevent a web application from making requests using potentially dangerous URL schemas such as
Authentication on Internal Services
Services such as Memcached, Redis, Elasticsearch, and MongoDB do not require authentication by default. Server-Side Request Forgery vulnerabilities could provide an attacker with the opportunity to access some of these services without any authentication standing in the way. Therefore, it’s best to enable authentication wherever possible as another defense mechanism.
Published at DZone with permission of Ian Muscat, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.