SSRF vs CSRF: What is Server-Side Request Forgery?

SSRF vs CSRF: What is Server-Side Request Forgery?

·

12 min read

SSRF vs CSRF: What is Server-Side Request Forgery?

Most developers will have heard of Cross-Site Request Forged (CSRF) before. It’s a constant threat that affects any website with a form or that performs any actions, and we typically have to mess around with CSRF tokens, XSRF headers, SameSite cookies, and more to ensure our apps are protected.

Like I said, it’s a significant issue!

But what about SSRF? Have you heard of it before? Do you even know what it means?

SSRF stands for Server-Side Request Forgery, and although both describe forged requests, they differ greatly from CSRF. CSRF is about compromising the browser and the user, while SSRF is about compromising the server and the environment.

Also, SSRF has its own OWASP Top 10 category, while CSRF has to share with others.

What is SSRF?

SSRF, or Server-Side Request Forgery, is a type of security vulnerability where an attacker tricks a server into making unauthorized requests to internal or external resources. In an SSRF attack, the attacker manipulates the server to send requests to locations it normally shouldn’t have access to, such as private internal systems or sensitive external APIs. This vulnerability can lead to data exposure, unauthorized actions, or even full control of the compromised server.

Protecting your API from SSRF requires a multi-layered approach, as relying on simple validation might not be enough. Many developers unknowingly make critical mistakes when securing APIs, exposing them to threats like SSRF. For example, improper input validation or the absence of proper access controls can easily open doors to such attacks. Moreover, it’s crucial to ensure that backend services are shielded from any unauthorized access attempts through carefully crafted network policies and role-based access controls (RBAC).

For more details on common mistakes and how to avoid them, check out this detailed guide on securing your API incorrectly. It breaks down common misconceptions and outlines best practices for keeping your API safe.

Unlike Cross-Site Request Forgery (CSRF), which targets the user’s browser, SSRF specifically exploits the server side of web applications, making it a more dangerous and complex threat. Let’s break it down and explore it even further below.

Server-Side Attacks

There are two sides to web apps: the client side, which runs in the browser and encompasses the visual elements and user interface, and the server side, which runs on the server and has your business logic, database, configuration, etc.

Client-side attacks and vulnerabilities run in the browser, usually within the victim’s browser. This gives the attacker access to the victim’s account and session, and depending on the vulnerability, the scope can be quite broad—although it is still tied to what is available in the browser and what the victim has access to. You also need to get the victim to run your payload somehow. Sometimes, this is easy, and other times, it’s quite difficult.

By comparison, Server-side attacks and vulnerabilities run on the server (which you probably guessed, given the name). This means that rather than exploiting a victim’s browser and user account, you’re exploiting functionality within the server itself - making the server perform actions it’s not supposed to be doing. SQL Injection is a good example of this - you’re modifying an existing SQL query to get it to retrieve information or perform actions it’s not supposed to do.

The other aspect of Server-side attacks that’s worth mentioning is that you’re often working blindly to find and exploit them. Client-side attacks, on the other hand, can usually be found and tested easily within your own browser before seeking to compromise your victim.

Request Forgery

As the name suggests, a forged request is when the attacker tricks a system into making requests that look legitimate but are unauthorized or unintended. This can allow an attacker to perform actions they normally would not be able to perform or access resources they should not be allowed to access.

During a Forged Request, the target system receives a request that looks legitimate but is actually a forgery. This forged request will come from a source the target trusts and contain valid authorization. Maybe it has the right session cookie or a valid authorization header, or maybe the IP address is allow-listed, or (and this will be important later) it’s arrived via a private network. It doesn’t matter what the reason is; the target trusts the request's source, believes it’s legitimate, and authorizes it to perform the requested action or return the requested resource.

How SSRF Attacks Work

Understanding SSRF Attacks

If we first think about a CSRF attack, they work by running malicious javascript within the victim’s browser, which makes a forged request to the server. As far as the server is concerned, the request comes from a real user who has been authenticated, and the server accepts the request and performs the action. (This assumes the site is vulnerable to CSRF attacks and has no protections in place.)

If we apply this to SSRF, the concept is roughly the same. If we can trick the server into making a specific request, we can perform actions or extract specific information that we cannot access.

Example of SSRF Attack

Consider this example:

We have a server sitting behind a cloud-based firewall (WAF), which protects it from DDoS attacks, detects brute-force and credential-stuffing attempts, and blocks other malicious traffic from reaching the server.

SSRF vs CSRF: What is Server-Side Request Forgery?

To compromise this server, we need to bypass the firewall and send our requests directly to it. However, the domain name points to the firewall, which means our only IP address is for the firewall and not the server behind it.

So, in order to get this server's IP address, we need to trick the server into giving it to us. If the application makes external requests to user-controlled URLs, such as to download and cache avatar images, then it gives us an opening we can abuse.

The attacker can submit a unique URL to a server they control and monitor their logs for the request from the target server:

SSRF vs CSRF: What is Server-Side Request Forgery?

The request will come from an IP address, which may be the target server's raw IP address. If this is the case, the attacker can bypass the firewall and make requests directly to the target server.

SSRF vs CSRF: What is Server-Side Request Forgery?

What Else Can You Do with SSRF?

The above example is a very simple example that can be abused to make other attacks more effective. However, you can also perform attacks with SSRF on its own.

Denial of Service

In the above example, we use an image URL to identify the server’s IP address. However, you could easily provide a URL to a huge image file, which the server would attempt to download and process. If the file is big enough, it may cause the server to run out of disk space or memory, preventing it from handling any more requests and effectively taking it offline.

In situations like this, rate limiting can be a crucial defense mechanism. By limiting the number of requests a user can make or setting a maximum payload size, you can prevent attackers from overwhelming your server with oversized files or excessive requests. Rate limiting prevents denial-of-service (DoS) attacks and ensures that your server resources are allocated fairly and are not monopolized by malicious actors.

Rate limiting is an essential yet sometimes overlooked practice in API security. For a deeper look into its importance and how it can safeguard your API, read this article: Who cares about rate and resource limiting?

Why go to the effort of sending millions of requests to DDoS a server when a single request can have a disastrous result?

Data Leaks

If the application accepts user-defined URLs, accesses them, and then returns the results from that request to the user in some format, it allows the attacker to read data from the server's perspective. This often inherits a privileged position, sometimes by allowing access to internal resources inside a private network that cannot be accessed from the outside, or since the server itself is automatically trusted, or maybe these requests are performed with additional headers that authorize requests.

One of the critical issues that arise during an SSRF attack is the improper handling of sensitive data. APIs that return too much information or expose internal endpoints can inadvertently leak vital data, including server metadata, authentication tokens, or even personal user data. Developers must carefully sanitize all returned data, ensuring that nothing sensitive is returned to the user. Furthermore, server-side validation should limit which URLs can be accessed via API requests, preventing unauthorized external or internal data exposure.

To learn more about preventing sensitive data leaks through your API responses, you can explore this comprehensive guide on not returning data from your API.

To explore this further, let’s examine the Capital One breach in 2019. A lot has been written about this, and there are differing opinions regarding the exact exploitation method, so I’ll focus on an article by Riyaz Walikar titled "An SSRF, privileged AWS keys, and the Capital One breach."

Real-World Example: The Capital One Breach

In the attack, “the attacker gained access to a set of AWS access keys by accessing the AWS EC2 metadata service via an SSRF vulnerability.” With access to these keys, they could access the S3 buckets in the account and all of the data stored within them.

🤷🏻 Another week, another massive data breach

Capital One, the 5th largest U.S. credit card issuer, suffered a #databreach exposing personal info of more than 100 million credit card applicants in the U.S. & 6 million in Canada.

Details ➤ https://t.co/IVyTp6Evh5

—by @Swati_THN pic.twitter.com/Vi485AtiEz

— The Hacker News (@TheHackersNews) July 30, 2019

In case you’re not familiar, Cloud and VM providers usually provide internal metadata endpoints that all of the servers they provision are allowed to access. These endpoints include a bunch of boring information (IP address, network configuration, etc.) and often some really sensitive information, too.

This can include API keys, public and private keys, authentication tokens, etc. What the provider includes depends on the provider, but it’s designed to make it easy for automated provisioning scripts and applications to access the environment-specific details without user intervention.

Given what we know about SSRF now, you should be able to connect the dots and see that a successful SSRF attack would be able to make a request to one of these metadata endpoints. When this attack occurred, there were no additional protections, so a simple request through SSRF was able to retrieve the metadata for the server.

Unauthorized Actions Through SSRF

I haven’t been able to scrounge up the details, but this particular SSRF vulnerability must have somehow provided the retrieved data back to the user. AWS provides a specific metadata endpoint that provides IAM Role credentials (IAM - authentication & authorization) for the server. The article states, “It appears that this role had excessive privileges allowing the listing and access to S3 storage. This privilege was used to list the buckets and download them locally.

ubuntu@ip-xxx-xx-xx-x:~$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ISRM-WAF-Role
{
  "Code" : "Success",
  "LastUpdated" : "2019-08-03T20:42:03Z",
  "Type" : "AWS-HMAC",
  "AccessKeyId" : "ASIA5A6IYGGDLBWIFH5UQ",
  "SecretAccessKey" : "sMX7//Ni2tu2hJua/fOXGfrapiq9PbyakBcJunpyR",
  "Token" : "AgoJb3JpZ2luX2VjEH0aCXVzLWVhc3Qt[...]8RXr1axpYnJv2GHb8h/det89iwpyk77+8YcEvRc+DGTLIcUIxDoirgck9bpP3EBXfs=",
  "Expiration" : "2019-08-04T03:16:50Z"
}

From that point onwards, the attacker could use the credentials they had obtained to access data within the S3 buckets.

It’s worth pointing out that this was only possible because the output of the request was sent back to the attacker in some form. If this data was not retrievable, making the GET request to the metadata service wouldn’t have exposed anything on its own.

In addition to controlling what information is returned, you should also implement rate limiting to reduce the impact of potential SSRF attacks. Rate limiting can prevent attackers from flooding your API with requests, reducing the likelihood of denial-of-service (DoS) attacks or large-scale data exfiltration. Even if an attacker can make a forged request, rate limiting will limit how frequently they can exploit it, mitigating the damage.

Rate limiting is often overlooked but is essential for ensuring the stability and security of APIs. Read more about why rate-limiting matters in this blog post: Who cares about rate and resource limits?

One common way to do this is through a web preview or PDF generator, which takes a user-defined link and takes a screenshot (or PDF export) of the user’s URL. If the application isn’t blocking internal URLs, then this could very easily be used to obtain a screenshot of an internal metadata URL - complete with sensitive information being revealed.

Note that AWS has made some changes to prevent this attack from occurring. This is common among cloud/VM providers, which makes this style of attack significantly harder.

Unauthorised Actions

Even if you can’t retrieve the output from a request, you may still be able to perform actions on the server. Let’s take a look at the article “How I Chained 4 Vulnerabilities on GitHub Enterprise, From SSRF Execution Chain to RCE!” by Orange Tsai.

The whole article is a great example of using smaller bugs like SSRF and chaining them into a significant attack, but I want to touch on the first bug, titled “First Bug - Harmless SSRF.”

In his article, he identifies that Github's Webhook feature is vulnerable to SSRF. It sends a blind POST request to an endpoint the user defines. The URL has some limitations, but they find a way to bypass those and run requests against localhost.

The question is, what can be done with just a POST request?

Well, it turns out that “There is an Elasticsearch service bound on port 9200. In the shutdown command, Elasticsearch doesn’t care about whatever the POST data is. Therefore, you can play its REST-ful API for fun :P

All it takes is creating a Webhook for the following URL, and the Elasticsearch service will be shut down whenever it’s run.

http://0:9200/_shutdown/

In this specific case, there is limited scope beyond denial of service - but the concept is applicable to any endpoint that would take a blind POST request within a private network. The potential for abuse is quite significant if the right endpoints exist and an attacker can find them.

Conclusion

I like to think about SSRF as a creative vulnerability. It’s not straightforward like Cross-Site Scripting (XSS) or SQL Injection (SQLi), where you just need to find the right combination of characters that allow some JavaScript to run. Instead, you must bypass limited controls, find hidden endpoints, and get creative to extract the information you want.

For hackers, this may be their sort of fun. Given how SSRF is often overlooked or misunderstood, there are probably a lot of vulnerable apps just waiting to be found. As developers, we need to understand how SSRF works and what sort of things can be done with it if we have a chance of stopping it.

If you’re building an API, part of finding an attacker who is trying to exploit SSRF is being able to observe our APIs.

Start optimizing your API performance today with Treblle. Experience the benefits of real-time monitoring, comprehensive logging, and actionable insights. See how Treblle can enhance your API observability and help you maintain robust and reliable APIs!

Talk to our API Expert