Stacie Farmer

Endlessly learning

OWASP Top Ten - Server-Side Request Forgery (SSRF)

July 11, 2022

SSRF (Server-Side Request Forgery) is a difficult vulnerability to find and can be a challenge to exploit. But when an attacker does find it in your app, they have the potential to bypass access controls, leak confidential data, and even execute code - all using your server.

It’s a welcome addition to the 2021 OWASP Top Ten list.


All examples of potential attacks in this article are for demonstration and educational purposes only. They should never be used outside of a lab environment or to harm other computers, users, etc.


What is Server-Side Request Forgery?

SSRF commonly occurs because a URL, which will be fetched by the app, can be modified by the client.

For example, imagine your web app needs to get stock info from an external API - like the example from PortSwigger here.

When a customer clicks on a button to ‘Check Availability’, that triggers a POST request to the external API - http://stock.weliketoshop.net:8080/product/stock/check?productId=6&storeId=1

Instead of hard-coding the API’s URL, it’s referenced in the HTTP Request, like this:

POST /product/stock HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 118

stockApi=http://stock.weliketoshop.net:8080/product/stock/check%3FproductId%3D6%26storeId%3D1

Since it’s in the HTTP Request, this URL can be modified by the client (meaning a user or an attacker).

Since your web server is the one making the call to the URL, this can allow an attacker to use your server to call external or internal URL’s.

For example, what if the attacker intercepted that POST Request and changed it to localhost, like this:

POST /product/stock HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 118

stockApi=http://localhost

But localhost is protected against external access, you might say.

You forget - this is your web server making the call to localhost and your web server is on your internal network. This means an attacker can use your web server to make a request for resources on the internal network.

What’s the harm with accessing localhost?

Depending on how your network is set up, you could have a lot of goodies on localhost that you don’t want external entities accessing.

For example, you could have:

  • localhost/phpmyadmin
    • you wouldn’t want an attacker gaining access to that page then brute forcing usernames and passwords
  • localhost/admin
    • you may not even set up access control to certain internal pages, because you think there’s no way someone can get through your firewall

The list can go on and on. An attacker could even enumerate through the port numbers to see what services you do have available internally and check if any of them have exploitable vulnerabilities.

Maybe you have AWS metadata stored on 169.254.169.254. An attacker who’s found an SSRF vulnerability is highly likely to check there for metadata keys.

Once an attacker gets in, there is a lot they could potentially do - all the way up to remote code execution.


More Advanced SSRF Attacks

Finding an exploitable URL field is a very common way to exploit SSRF. But there are also more advanced ways to do it that you might not think about.

How about files that are parsed by the application? Maybe there’s a PDF generator or your app allows customers to upload PDFs, Word Docs, or Excel files. Each of those types of files are a collection of XML data behind the scenes and could contain XXE (XML External Entity) vulnerabilities that allow SSRF.

For example, NahamSec’s post - My Expense Report Resulted in a Server-Side Request Forgery (SSRF) on Lyft, clearly explains how he found a way to inject <link> tags into a PDF generator (WeasyPrint) on Lyft’s app.

This was not a simple attack and it definitely took a lot of time and investigating to figure out all the pieces that needed to be put in place, but it ultimately gave him access to Lyft’s internal network. Using that access, he was able to view their AWS metadata instance keys and possibly do even more.


Possible Ways to Help Prevent Server-Side Request Forgery

As usual, this is a tough one to prevent completely, but the following tips from OWASP can help:

  • Network Side:
    • Segment remote resource access functionality in separate networks
    • Enforce “deny by default” firewall policies or network access control rules to block all but essential intranet traffic
  • Application Side:
    • Sanitize and validate all client-supplied input data
    • Enforce the URL schema, port, and destination with a positive allow list
      • Do not mitigate SSRF via the use of a deny list or regular expression. Attackers have payload lists, tools, and skills to bypass deny lists.
    • Do not send raw responses to clients
    • Disable HTTP redirections
    • Be aware of the URL consistency to avoid attacks such as DNS rebinding and “time of check, time of use” (TOCTOU) race conditions

Another strong protection option could be to use a helper server to fetch any external resources the web app needs. The helper server would be locked down to have no access to surrounding internal services and its sole function would be to retrieve resources for the web app server. This doesn’t prevent all SSRF attacks, but could greatly reduce the attack surface for certain companies. More information about this method can be found in this white paper - Preventing Server-Side Request Forgery Attacks


Sum It Up

An SSRF vulnerability can be a nasty beast if attackers find it in your web app. The likelihood of an SSRF vulnerability may be low, but the impact can be quite high, so it’s important to understand how these types of vulnerabilities happen and what you can do to prevent them.

Check out the resources below to help further your knowledge and keep learning so you can build customized solutions that work for your situation.

Further Reading