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
, orhttp://internal-service.local
.Try sensitive cloud metadata endpoints, such as
http://169.254.169.254/latest/meta-data/
(AWS) orhttp://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
) usesX-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
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
).Victim Interaction: The victim visits
example.com
, which loads malicious JavaScript from the attacker’s server.DNS Rebinding: The DNS record for
example.com
is updated to resolve to the internal IP (e.g.,192.168.1.3
).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.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:
Configures
example.com
to resolve to their server (203.0.113.1
) with a TTL of 1 second.Tricks a victim into visiting
http://example.com
, which loads malicious JavaScript.Updates the DNS to resolve
example.com
to192.168.1.3
.The JavaScript sends a GET request to
http://example.com/admin
, retrieving sensitive data.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
to127.255.255.255
(e.g.,127.0.0.2
).Shortened Form:
127.1
.Padded Form:
127.000000000000000.1
.All Zeroes:
0.0.0.0
or0
.Decimal Form:
2130706433
(equivalent to127.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
(encodeslocalhost
).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 equals127.0.0.1
in decimal).Octal notation:
017700000001
.Shorthand notation:
127.1
(a valid alternative for127.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.
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 anhttps://
URL instead.Some filters fail when handling
ftp://
orfile://
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:
Validate the
stockApi
parameter, which points to a legitimate domain (weliketoshop.net
).Make a request to this external domain, which then redirects to
http://192.168.0.68/admin
(an internal service).The application follows the redirection, accessing an internal administrative interface, bypassing internal access controls.
How This Works
The SSRF vulnerability works because the application:
Validates the initial domain (
weliketoshop.net
), allowing it through the filter.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.
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.
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