← homeEducation (Освіта)

What is Server-Side Request Forgery (SSRF) and why is it dangerous

Server-Side Request Forgery (SSRF) is a vulnerability in web applications that allows an attacker to make the server perform an HTTP request to a resource that the attacker cannot directly access. At first glance, thi...

Table of contentsClick link to navigate to the desired location
This content has been automatically translated from Ukrainian.
Server-Side Request Forgery (SSRF) is a vulnerability in web applications that allows an attacker to make the server perform an HTTP request to a resource that the attacker cannot directly access.
At first glance, this may not sound very dangerous: well, the server made an HTTP request. But the problem is that the server often has access to internal resources that are not available on the public internet.
For example, to internal APIs, databases, administrative panels, or cloud metadata services.

How SSRF Works

Imagine a simple service that allows you to download a file by URL:
https://example.com/download?url=https://tseivo.com/image.jpg
The server receives the address and downloads the file itself:
User
    │
    │ URL
    ▼
Web Application
    │
    │ HTTP request
    ▼
https://tseivo.com/image.jpg
This is a perfectly normal function.
But if the server does not validate the provided URL, the user can specify an internal address instead of an external site:
https://example.com/download?url=http://127.0.0.1:8080/admin
Now the request to 127.0.0.1:8080 is executed by the server itself.
For the attacker, this can be particularly interesting if an internal service is running on that port.

Why the Server Can See What the Attacker Cannot

Imagine the infrastructure:
                    Internet
                       │
                 ┌─────▼─────┐
                 │ Web server │
                 └─────┬─────┘
                       │
             ┌─────────┼─────────┐
             ▼         ▼         ▼
         Internal    Database   Admin
           API                  panel
Only the Web Server is accessible from the internet.
But the Web Server itself may have access to the Internal API, databases, or the administrative panel.
SSRF effectively uses the server as a proxy:
Hacker
   │
   │ "Make a request here"
   ▼
Web Server
   │
   │ request on behalf of the server
   ▼
Internal Service
This means that the firewall may effectively block the attacker's direct access to the Internal API, but SSRF allows bypassing this restriction through a server that already has the necessary access.

SSRF and localhost

One of the simplest attack vectors is to target localhost:
http://127.0.0.1/
http://localhost/
Or to a specific port:
http://127.0.0.1:3000/
http://127.0.0.1:8080/
This can allow access to services that intentionally listen only on the local interface.
For example, an internal administrative panel may be running in production:
http://127.0.0.1:8080/admin
It is not accessible from the outside.
But if your application has SSRF, it can make a request to this panel itself.

SSRF in Cloud Infrastructure

SSRF becomes particularly serious in cloud environments.
In some cloud platforms, the server can access a special metadata service, through which it can obtain information about the current instance or its credentials.
For example, the application may have access to the metadata endpoint, while the attacker does not.
If the attacker finds SSRF, they may try to force the server to access this endpoint.
In the worst case, this can lead to obtaining credentials and further access to the resources of the cloud infrastructure.
That is why SSRF is often viewed not just as a problem with HTTP requests, but as a potential pathway to compromising the entire infrastructure.

Where SSRF Most Often Occurs

SSRF should be looked for in functions where the server receives a URL from the user.
For example:
  • uploading images by URL;
  • importing data from an external API;
  • webhooks;
  • URL validation;
  • generating webpage previews;
  • PDF or screenshot services;
  • URL unfurling in chats;
  • integrations with other services;
  • functions like fetch, proxy, or download.
For example, dangerous code may look very simple:
url = params[:url]

response = HTTP.get(url)
The problem here is not with HTTP.get itself.
The problem is that the user effectively gained the ability to determine where the server will make a request.

Why Simply Validating the URL is Not Enough

One might think that it is enough to block:
localhost
127.0.0.1
But protection against SSRF is more complex.
There are various representations of IP addresses, DNS tricks, redirects, and other ways to bypass naive validation.
For example, the server may first validate the domain:
https://example.com
and then receive an HTTP redirect to an internal address.
Therefore, validation should not only be performed on the URL that the user initially provided but also on the final address to which the connection is actually established.

How to Protect Against SSRF

The best protection is to not allow the user to make arbitrary server-side requests.
If that is not possible, several layers of protection can be used.

1. Allowlist

Instead of a blacklist, it is better to only allow known domains:
api.example.com
images.example.com
and not try to enumerate all the addresses that need to be blocked.

2. Block Private Addresses

Access to should be blocked:
127.0.0.0/8
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
as well as other special-use and link-local addresses.

3. Control Redirects

Do not allow:
external-site.com
        ↓
internal-service
Validation should also apply to redirects.

4. Limit Protocols

If the functions only need HTTP/HTTPS, do not allow arbitrary schemes like:
file://
gopher://
ftp://

5. Network Isolation

Even if SSRF occurs, the server should not have the ability to reach critical internal systems.
This is a good example of the principle of defense in depth: not relying on a single protective mechanism.

Blind SSRF

There is another interesting variant - blind SSRF.
In this case, the server makes a request to a resource, but the result is not returned to the attacker.
For example:
Attacker
   │
   │ URL
   ▼
Web App
   │
   │ request
   ▼
Internal Service
The attacker does not see the response, but can still determine that the request occurred through indirect signs.
For example, the server may contact an endpoint controlled by the attacker, and the attacker will see the incoming request in their logs.
Blind SSRF is harder to exploit, but it can still be a serious problem.

SSRF is Not Just "Making a Request"

The main danger of SSRF lies in the difference between what the user can see and what the server can see.
The user may only have access to:
Internet
while the server has access to:
Internet
+
Internal network
+
localhost
+
Cloud metadata
+
Private APIs
SSRF allows the attacker to leverage these additional privileges of the server.
Therefore, any function of the form:
"Give me a URL, and I will download it myself"
should be considered a potential SSRF attack surface.
In short: SSRF is a situation where an attacker forces your server to make network requests on their behalf. And the more internal resources the server has access to, the more serious the consequences of such a vulnerability can be.

🔥 More posts

All posts
Programming (Програмування)Apr 3, '24 06:49

What is SSR (Server Side Rendering)?

SSR, or Server Side Rendering, is a technique used to generate HTML content on the server and sen...