Server-Side Request Forgery (SSRF)

What is SSRF?

SSRF occurs when an attacker can control the URL or IP address used by a server to make HTTP requests. For example, if a web application fetches a user-provided URL without validating it, an attacker could trick the server into accessing internal services like http://localhost:8080 or external systems under their control. This can lead to severe consequences, such as:

  • Accessing internal systems: Interacting with services like databases, admin panels, or metadata endpoints (e.g., AWS metadata at http://169.254.169.254).

  • Bypassing firewalls: Reaching firewalled resources that are inaccessible from the public internet.

  • Data exfiltration: Leaking sensitive data to attacker-controlled servers.

  • Service disruption: Triggering unauthorized actions on internal or external systems.

Example Scenario

Imagine a web application with a feature that fetches a user-provided URL to display a preview of a webpage. The backend processes the request as follows:

GET /preview?url=http://example.com

If the application does not validate the url parameter, an attacker could supply http://localhost/admin or http://169.254.169.254/latest/meta-data/ to access internal resources. This is the essence of SSRF.

Identifying SSRF Vulnerabilities

To identify SSRF vulnerabilities, focus on application features that involve server-side requests. These are often entry points where user input influences the destination of HTTP requests. Below are key areas to investigate, along with testing strategies and examples.

1. URL Import Features

Applications that fetch external resources, such as image importers or API data fetchers, are prime candidates for SSRF. If the server blindly trusts user-supplied URLs, attackers can target internal endpoints.

Testing Strategy:

  • Identify endpoints that accept URLs as input (e.g., /fetch?url=... or /import?url=...).

  • Test with internal URLs like http://localhost, http://127.0.0.1, or http://internal-service.local.

  • Try sensitive cloud metadata endpoints, such as http://169.254.169.254/latest/meta-data/ (AWS) or http://metadata.google.internal/computeMetadata/v1/ (Google Cloud).

Example: A web application allows users to import images via a URL:

POST /import-image
Content-Type: application/json
{"url": "http://example.com/image.jpg"}

Test by submitting:

{"url": "http://localhost:8080/admin"}

If the server responds with data from the internal admin panel or an error indicating a connection attempt, you’ve likely found an SSRF vulnerability.

2. File Upload Mechanisms

File uploads, especially for formats like PDFs, SVGs, or Office documents, can be exploited if the server processes embedded URLs. For instance, an SVG file might include a reference to an external resource that the server fetches.

Testing Strategy:

  • Upload or trigger generation of files containing embedded URLs (e.g., <iframe src="http://localhost">).

  • Test with URLs pointing to internal services or attacker-controlled servers.

  • Monitor for server responses or use out-of-band (OAST) tools like Burp Collaborator to detect callbacks.

Example:

Inject an iframe pointing to an internal resource:

<iframe src="http://169.254.169.254/latest/meta-data"></iframe>

If the server renders the PDF with this embedded content and processes the request, it may lead to SSRF and exposure of internal services.

Reference: The PDF Trojan Horse: Leveraging HTML Injection for SSRF and Internal Resource Access.

3. Headless Browsers / HTML Rendering

Features that generate PDFs, screenshots, or previews using headless browsers are susceptible to SSRF. These systems often parse HTML content and fetch embedded resources, which can be manipulated.

Testing Strategy:

  • Inject URLs into HTML-like inputs (e.g., <iframe src="http://internal-service"> or <img src="http://localhost">).

  • Try accessing internal services, cloud metadata, or local APIs like http://127.0.0.1:9222/json.

  • Use OAST tools (e.g., Burp Collaborator) to confirm blind SSRF via callbacks.

Example: A dashboard-building app allows users to export their dashboards to PDF. Each dashboard contains user-supplied JSON data, which gets rendered in a headless browser:

{
  "items": [
    {
      "type": "iframeobject",
      "url": "https://attacker.com"
    }
  ]
}

When this data is rendered, the attacker’s iframe loads in the backend Chromium instance. If the attacker hosts HTML with a nested iframe pointing to internal services like http://127.0.0.1:9222/json, the server may leak sensitive information like browser tabs or session tokens in the rendered PDF.

Reference: SSRF on a Headless Browser Becomes Critical.

4. Server Status and Monitoring Features

Applications that query internal services (e.g., /health, /status, /check) are often vulnerable to SSRF if they allow users to specify the destination URL.

Testing Strategy:

  • Identify endpoints that accept a url or similar parameter.

  • Test with internal IPs like 127.0.0.1 or cloud metadata services (169.254.169.254).

  • Check response codes, timings, or use response validation (if available) to confirm access.

  • Use OAST tools for blind SSRF detection.

Example: A cloud monitoring system allows setting a URL for uptime checks:

bashCopyEditGET /check-status?url=http://monitoring-service

Test with:

bashCopyEditGET /check-status?url=http://169.254.169.254/computeMetadata/v1/project/project-id
Headers: Metadata-Flavor: Google

Even without a visible response body, SSRF can be confirmed through:

  • Fast response time (e.g., 2ms) indicating internal access

  • Response validation features (e.g., check if response contains a known string)

  • Brute-force or binary search over response body to reconstruct sensitive content

Reference: 31k SSRF in Google Cloud Monitoring.

5. Proxy Implementations

Reference: Server-Side Request Forgery on Havoc C2.

6. File Storage Integrations

Integrations with file storage services like Amazon S3, Google Drive, or Dropbox are common in modern web applications, especially for file uploads, downloads, and imports. These integrations often involve server-side HTTP requests — making them prime SSRF targets.

Testing Strategy:

  • Test Import/Export Features: Look for upload/import endpoints that take a URL or a file path. Example payloads:

    jsonCopyEdit{"url": "http://169.254.169.254/latest/meta-data/"}

    If the server fetches this internal AWS metadata endpoint, SSRF is confirmed.

  • Manipulate Cloud Bucket/Path:

    • Try changing the bucket name or file path in S3-style URLs:

      bashCopyEdithttps://s3.amazonaws.com/mybucket/file.pdf
      → https://s3.amazonaws.com/another-bucket/../../etc/passwd
  • Use OAST Tools:

    • Inject out-of-band URLs (e.g., Burp Collaborator, OASTify) to detect server-initiated requests.

7. Path Parameters and Host Headers

Applications that dynamically construct server-side requests using path parameters or host headers can be manipulated by attackers to access internal systems. This can lead to SSRF, privilege escalation, and even complete account takeovers, depending on the logic.

Testing Strategy

  • The app (abc.victim.com) uses X-Forwarded-Host to determine request origin.

  • Attacker sets:

    X-Forwarded-Host: attacker.com
  • The app sends SSRF requests to attacker.com (attacker's server), expecting auth/permission responses.

  • Attacker's server responds with forged authorization:

    { "type": "admin" }
  • Application trusts the response and grants admin access.

  • As an admin, the attacker discovers a flawed add user feature — even with 403 Forbidden, users are created.

  • Attacker creates a new admin user, achieving organization-wide takeover.

Reference: Host Header Injection to Complete Organization Takeover .

Blind SSRF

Blind SSRF occurs when an attacker can trigger server-side requests but cannot see the full response, only a status code or indirect feedback. This makes detection challenging but not impossible.

Detection Techniques:

  • Out-of-Band (OAST) Testing: Use tools like Burp Collaborator or Interact.sh to generate a unique domain (e.g., attacker.oastify.com) and monitor for HTTP or DNS requests.

  • Time-Based Testing: Measure response times to infer whether a request was successful (e.g., a delay may indicate a connection to a slow internal service).

  • Error Messages: Analyze error responses for clues about internal services or connection attempts.

Example: Test a URL import endpoint with:

POST /import
Content-Type: application/json
{"url": "http://attacker.oastify.com"}

If your OAST tool logs an HTTP or DNS request, you’ve confirmed blind SSRF.

Common Mistake: Bug bounty hunters often report DNS pingbacks (e.g., via Burp Collaborator) as SSRF without further validation. Most platforms consider DNS pingbacks alone out of scope, as they don’t confirm actual request execution. Always verify impact by accessing internal resources or triggering observable effects.

SSRF with DNS Rebinding

DNS rebinding is a sophisticated technique that combines SSRF with DNS manipulation to bypass the Same-Origin Policy, allowing attackers to access internal resources via a victim’s browser.

How It Works

  1. Domain Acquisition: The attacker controls a domain (e.g., example.com) and configures its DNS with a low to switch between their server and an internal IP (e.g., 192.168.1.3).

  2. Victim Interaction: The victim visits example.com, which loads malicious JavaScript from the attacker’s server.

  3. DNS Rebinding: The DNS record for example.com is updated to resolve to the internal IP (e.g., 192.168.1.3).

  4. Malicious Request: The JavaScript sends a request to http://example.com/sensitive-endpoint, which resolves to the internal service. Since the origin remains the same, the Same-Origin Policy is not violated.

  5. Data Exfiltration: The response is sent to an attacker-controlled domain (e.g., harmful.example.com).

Example: An internal web application at http://192.168.1.3/admin is only accessible within the organization’s network. An attacker:

  1. Configures example.com to resolve to their server (203.0.113.1) with a TTL of 1 second.

  2. Tricks a victim into visiting http://example.com, which loads malicious JavaScript.

  3. Updates the DNS to resolve example.com to 192.168.1.3.

  4. The JavaScript sends a GET request to http://example.com/admin, retrieving sensitive data.

  5. The data is exfiltrated to http://harmful.example.com.

Tools:

  • rbndr.us: Generates hostnames for DNS rebinding tests.

  • Singularity: A DNS rebinding attack framework (GitHub: nccgroup/singularity).

  • DNSrebinder: A minimal DNS server for testing rebinding (GitHub: mogwailabs/DNSrebinder).

Reference:

SSRF via DNS Rebinding (CVE-2022–4096)

rbndr.us dns rebinding service

GitHub - nccgroup/singularity: A DNS rebinding attack framework.

SSRF Filter Bypasses

Modern applications often implement filters to block SSRF attacks, but these can be bypassed using creative techniques. Below are common methods to evade SSRF protections.

1. Open Redirects

If the application has an open redirect vulnerability, attackers can use it to redirect requests to internal services.

Example: An endpoint /redirect?url=http://example.com redirects to the provided URL. Test with:

GET /redirect?url=http://localhost:8080

If the server follows the redirect to the internal service, you’ve bypassed the filter.

2. IP Address Obfuscation

Filters often block obvious internal IPs like 127.0.0.1. Use alternative representations to bypass them:

  • Localhost Range: 127.0.0.0 to 127.255.255.255 (e.g., 127.0.0.2).

  • Shortened Form: 127.1.

  • Padded Form: 127.000000000000000.1.

  • All Zeroes: 0.0.0.0 or 0.

  • Decimal Form: 2130706433 (equivalent to 127.0.0.1).

  • Octal Form: 0177.0000.0000.0001.

  • Hexadecimal Form: 0x7f000001.

  • IPv6 Loopback: 0:0:0:0:0:0:0:1 or ::1.

  • IPv4-mapped IPv6: ::ffff:127.0.0.1.

Example: Test an endpoint with:

POST /fetch
Content-Type: application/json
{"url": "http://2130706433"}

If the server resolves 2130706433 to 127.0.0.1, the filter is bypassed.

3. Protocol-Based Bypasses

Filters often focus on HTTP/HTTPS but may overlook other protocols like ftp://, file://, or gopher://.

Example: Test with:

POST /fetch
Content-Type: application/json
{"url": "file:///etc/passwd"}

If the server reads the local file, you’ve bypassed the filter.

4. URL Encoding and Parsing Tricks

Filters may fail to normalize encoded or malformed URLs. Try:

  • URL Encoding: http://%6c%6f%63%61%6c%68%6f%73%74 (encodes localhost).

  • Double Encoding: http://%256c%256f%2563%2561%256c%2568%256f%2573%2574.

  • Null Bytes: http://localhost%00@attacker.com.

  • Mixed Case: HTTP://LOCALHOST.

Example: Test with:

POST /fetch
Content-Type: application/json
{"url": "http://%6c%6f%63%61%6c%68%6f%73%74"}

If the server fetches http://localhost, the filter is bypassed.

5. Parser Inconsistencies

Different URL parsers in the application stack (e.g., frontend vs. backend) may interpret URLs differently, allowing bypasses.

Example: Test with:

POST /fetch
Content-Type: application/json
{"url": "http://localhost#@attacker.com"}

If the backend parser ignores the fragment (#) and fetches http://localhost, you’ve found a bypass.

Reference: PayloadsAllTheThings

Useful Tools for SSRF Testing

Here are some powerful tools to automate and enhance SSRF testing:


Lab: Basic SSRF against the local server

Lab Description

This lab has a stock check feature which fetches data from an internal system.

To solve the lab, change the stock check URL to access the admin interface at http://localhost/admin and delete the user carlos.

Lab Solution

To access the "check stock" feature we click on any of the products as in the screenshot below.

Now check for this captured request in burp suite.

Now send the request to repeater.

Now change the URL of the stockApi to the one given in the lab description as shown in the screenshot below. This modification sends the request back to the server, to a location that is local to the server which is hosting the application.

Finally send this request and the response for the same is as shown in the screenshot below.

Now look for the path that will delete user Carlos and replace the stockApi URL with that as shown in the images below.

Finally send this request and as can be seen below the user has been deleted successfully and lab has been solved.

2- SSRF attacks against other back-end systems

In many applications, the server can communicate with internal back-end systems that are not directly accessible by users. These systems often have non-routable private IP addresses and are typically protected by network segmentation. However, because they are assumed to be unreachable from the internet, they often have weaker security measures.

In many cases, these internal systems contain sensitive functionality that does not require authentication, assuming that only trusted internal components will interact with them. This makes them prime targets for Server-Side Request Forgery (SSRF) attacks.

Example: Accessing an Internal Admin Panel

Consider the same shopping application example from before. Suppose the back-end system has an administrative interface hosted at http://192.168.0.68/admin, which is only meant to be accessed from inside the company's private network.

An attacker can target an internal admin panel using SSRF:

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

stockApi=http://192.168.0.68/admin11

Since the request originates from the application server (which is inside the organization's network), it may successfully access the private administrative interface, even though the attacker is external.

Private IP addresses are reserved address blocks used for internal network communication. Devices within a private network can communicate with each other using these addresses, but they cannot be accessed directly from the public internet.

Now consider this lab from Web Security Academy.

Lab: Basic SSRF against another back-end system

Lab Description

This lab has a stock check feature which fetches data from an internal system.

To solve the lab, use the stock check functionality to scan the internal 192.168.0.X range for an admin interface on port 8080, then use it to delete the user carlos.

Lab Solution

Access the check stock feature by clicking any product and using the check stock functionality as shown in the above screenshot.

Now check burp suite for the requests captured.

As shown in the screenshot above, the request selected contains the check stock feature.

Carefully note that as mentioned in the lab description, the address provided to us is not complete. To know the complete address where the admin interface is hosted, we will send this request to burp suite intruder and brute force for the correct address.

As shown in the above screenshot we replace the stockApi value with the URL to the IP given in the lab description which points to port 8080 to access the admin panel.

We replace the “X” with “1” and add the payload position over there as this will be replaced each time to check for the correct IP address.

In next step we set the payload as the numbers from 1 to 255 with step value as 1 as shown in the screenshot below.

The results from burp intruder are:

As can be seen in the results above, there is one request with status code 200 which means this is the successful request. The highlighted part is the correct IP address which hosts the admin panel over port 8080.

Now send this request to repeater.

Now in repeater, send the request and in the response look for the URL that will delete the user carlos.

Update the current value of stockApi with this URL and send the request.

This finally solves the lab.

3- Bypassing Blacklist-Based Input Filters in SSRF

Some applications attempt to prevent Server-Side Request Forgery (SSRF) by blocking requests containing specific hostnames (e.g., 127.0.0.1, localhost) or restricted paths (/admin). However, blacklist-based filtering is often weak and can be bypassed using various techniques :

1. Using Alternative IP Representations

  • Decimal notation: 2130706433 (which equals 127.0.0.1 in decimal).

  • Octal notation: 017700000001.

  • Shorthand notation: 127.1 (a valid alternative for 127.0.0.1).

Example: Instead of using http://127.0.0.1/admin, try http://2130706433/admin.

2. URL Encoding & Other Encoding Techniques

  • URL encoding: http://127%2E0%2E0%2E1/admin.

  • Double encoding: http://127%252E0%252E0%252E1/admin.

  • Hex encoding: http://0x7f.0x00.0x00.0x01/admin.

  • Base64 encoding (if applicable): aHR0cDovLzEyNy4wLjAuMS9hZG1pbg== (if the application allows decoding).

3. Case Variation Tricks

Some blacklist filters only block lowercase variations of keywords. If filtering is case-sensitive, you can try different capitalizations:

  • Bypassing localhost: LoCaLhOsT, lOcAlHoSt.

  • Bypassing /admin: /AdMiN, /ADMIN.

Tip: Try a combination of encoding and case variation for better success!

4. Using Open Redirects & External URLs

If an application blocks direct requests to sensitive endpoints, you can bypass the filter by using an open redirect on a different domain that forwards the request to the restricted resource.

  1. https://your-redirect.com/redirect?url=http://127.0.0.1/admin

5. Leveraging Different Redirect Codes & Protocols

Web servers use HTTP status codes for redirections. Some SSRF filters fail when handling certain redirect codes or protocol changes. You can experiment with:

  • 301 Moved Permanently

  • 302 Found (Temporary Redirect)

  • 307 Temporary Redirect (preserves the original HTTP method).

  • 308 Permanent Redirect (similar to 301 but stricter).

6.Protocol Switching:

  • If an application blocks http://127.0.0.1/admin, try redirecting from an https:// URL instead.

  • Some filters fail when handling ftp:// or file:// protocols.

Now consider this lab from Web Security Academy.

Lab: SSRF with blacklist-based input filter

Lab Description

This lab has a stock check feature which fetches data from an internal system.

To solve the lab, change the stock check URL to access the admin interface at http://localhost/admin and delete the user carlos.

The developer has deployed two weak anti-SSRF defenses that you will need to bypass.

Lab Solution

Access the check stock feature by visiting any product and clicking the check stock button as shown in the screenshot below.

Now check burp suite for the request captured.

Send this request to burp suite repeater and replace the current value of stockApi with the back-end system URL as shown in the screenshot below.

Now send the request and analyse the response.

As can be seen, the request has been blocked, this means there is some anti-SSRF defense mechanism which is blocking the request.

Now try URL encoding “/” and replacing it with its URL encoded counterpart and also try case variation in case of “localhost”. Finally send the request and analyse the response as shown in the screenshot below.

Now try to replace “localhost” with “127.0.0.1” and also try case variation in “admin” leaving “/” URL encoded only. Send the request and analyse the response as shown in the image below.

Now try to replace URL encoded “/” with “/” itself and also try some other case variation in “admin” and “localhost” as shown in the screenshot below. Finally send the request and analyse the response.

This means that the SSRF attack was successful and that we have got the access to admin panel.

Look for the path that will delete the user carlos as shown in the screenshot below.

Modify the value of stockApi as shown in the screenshot below and send the request.

This finally solves the lab.

The logic behind the lab was using an SSRF payload and by-passing the anti-SSRF security mechanism using payload obfuscation.

Bypassing SSRF Filters via Open Redirection

In such a scenario, even if a URL filter is in place to block dangerous domains or internal resources (like localhost or 127.0.0.1), an open redirection vulnerability may still allow attackers to bypass these filters. This happens when the application allows users to supply URLs that the backend server follows, and it supports HTTP redirections (such as HTTP 301, 302, or 307).

If the URL contains a legitimate domain that passes the filter, but redirects to a malicious internal IP or service, SSRF can still occur.

Example Scenario:

Consider the following scenario in a vulnerable application:

The application allows users to check the stock of products from an external API. The user submits a request such as:

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

stockApi=http://weliketoshop.net/product/nextProduct?currentProductId=6&path=http://evil-user.net

The URL /product/nextProduct contains a parameter path that redirects to any URL specified by the attacker:

/product/nextProduct?currentProductId=6&path=http://evil-user.net

In this case, it will redirect to http://evil-user.net.

An attacker can leverage this vulnerability to bypass the SSRF filter. Instead of providing a malicious internal URL (which would be blocked), they use the open redirection URL to reach an internal service or target:

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

stockApi=http://weliketoshop.net/product/nextProduct?currentProductId=6&path=http://192.168.0.68/admin

The server will:

  1. Validate the stockApi parameter, which points to a legitimate domain (weliketoshop.net).

  2. Make a request to this external domain, which then redirects to http://192.168.0.68/admin (an internal service).

  3. The application follows the redirection, accessing an internal administrative interface, bypassing internal access controls.

How This Works

The SSRF vulnerability works because the application:

  1. Validates the initial domain (weliketoshop.net), allowing it through the filter.

  2. Follows the redirect to an internal resource (http://192.168.0.68/admin), which the attacker controls.

Now consider this lab from Web Security Academy.

Lab: SSRF with filter bypass via open redirection vulnerability

Lab Description

This lab has a stock check feature which fetches data from an internal system.

To solve the lab, change the stock check URL to access the admin interface at http://192.168.0.12:8080/admin and delete the user carlos.

The stock checker has been restricted to only access the local application, so you will need to find an open redirect affecting the application first.

Lab Solution

Click on any product and then access the check stock feature as shown in the screenshot below.

Now check burp suite for the intercepted request and send it to repeater.

Now try accessing the admin functionality as done in the screenshot below.

The response to the above request is:

This means the request to this internal resource is being blocked, hence we need to find an open redirection that can help us access this restricted resource.

On further analysis we get the next product button as shown below and clicking it captures the request for the same in burp suite.

As shown in the screenshot above, the request for the next product contains the query parameter path which provides the potential of a possible open redirection.

Open redirection means a security flaw in a web application that allows an attacker to manipulate where the application redirects a user.

Hence we try redirecting this to “google.com” as demonstrated below.

As can be seen, there is indeed an open redirection vulnerability that allows the attacker to control the redirection path.

Since the stockApi has access to the internal resources thus we can not redirect from this request itself but we copy the path of this request and then paste it in the stockApi parameter, further we append the internal path in the query parameter path. This is demonstrated in the screenshots below.

copy the highlighted path
paste it in the stockApi parameter and also append the internal path in the path query parameter

Now the response for the above request is:

Since the original value of the stockApi was URL encoded hence we encode this value also by selecting it and pressing ctrl+U.

The request is modified as:

The response for the above request is:

This shows that we have successfully got access to the admin panel.

Now we look for the request that deletes user Carlos and modify the stockApi value accordingly as demonstrated in the screenshots below.

modified request

This finally solves the lab.

The logic behind the working of this attack is that, the stockApi parameter had access to the internal resources of the server but it did not allow direct access to them due to strict validation of the request. Thus we look for the request that has an open redirection vulnerability which means that the user has control over the URL where redirection takes place.

In this case the redirection was there in the “next product” request. We copy the path of this request and replace it with the value of stockApi since stock checking feature has access to internal resources and thus redirection to internal resources was not possible from the “next product” request itself.

Finally we replace the path parameter with the value of the path to the internal resource that is admin in this case. This finally gives us the access to the admin panel and the lab is further solved as per the steps explained above.

Last updated