Respuesta rápida: Un WAF (Web Application Firewall) filtra peticiones buscando patrones maliciosos. Un "bypass" consiste en reescribir tu carga para que no coincida con esas firmas sin perder su efecto: codificándola, alternando mayúsculas, insertando comentarios, dividiéndola con HPP o usando sintaxis alternativa. Se hace solo en objetivos autorizados y para demostrar que la vulnerabilidad subyacente existe pese al filtro.
¿Qué es un WAF y por qué se puede evadir?
Un WAF es una capa que inspecciona el tráfico HTTP y bloquea lo que parece un ataque, comparándolo con firmas y reglas (por ejemplo, "si ves <script> o UNION SELECT, bloquea"). Es una defensa útil, pero tiene una debilidad de fondo: filtra por patrones, no entiende la intención. Si consigues expresar la misma carga con una forma que la regla no reconoce pero el navegador o la base de datos sí interpretan, pasas.
Importante para no engañarte: un WAF bypass no es en sí una vulnerabilidad. Es la demostración de que una vulnerabilidad real (XSS, SQLi…) sigue siendo explotable pese al filtro. Sin fallo detrás, evadir el WAF no vale nada. Lo que reportas es el fallo; el bypass es la prueba de que el WAF no lo mitiga.
Ética por delante: todo esto se practica en laboratorios propios o en programas con scope que lo permita. Evadir defensas de un sistema sin autorización es ilegal. Aquí el objetivo es entender la técnica para reportar y para construir defensas mejores.
¿Qué tipos de WAF existen?
Antes de evadir conviene saber a qué categoría te enfrentas, porque cada una tiene puntos ciegos distintos:
- WAF de red / basados en firmas. Inspeccionan el tráfico buscando patrones conocidos (ModSecurity con el core rule set es el ejemplo clásico open source). Son los más evadibles con transformaciones, porque razonan por coincidencia de cadenas.
- WAF en la nube (CDN). Se colocan delante de la aplicación como servicio (los grandes CDNs ofrecen esta capa). Además del filtrado por firmas suelen sumar rate limiting, reputación de IP y challenges tipo captcha. Más difíciles, pero no infalibles.
- WAF basados en aplicación / RASP. Se integran dentro de la propia app y entienden mejor el contexto de la petición. Los más duros de evadir porque no razonan solo por patrones.
La clave común: todos, en mayor o menor grado, deciden con información incompleta. Cuanto más se apoye un WAF en firmas rígidas, más margen tienes para reescribir la carga sin que la reconozca.
¿Cómo fingerprintear un WAF?
Antes de evadir, identifica a qué te enfrentas. Cada WAF tiene tics reconocibles:
- Página o código de bloqueo característico. Manda una carga obviamente maliciosa (
?q=<script>alert(1)</script>) y observa: ¿un 403, un 406, un "Access Denied", una página de challenge? El formato delata al producto.
- Cabeceras y cookies. Algunos WAF inyectan cabeceras o cookies propias en la respuesta.
- Herramientas.
wafw00f es el clásico para fingerprintear el producto; sqlmap tiene --identify-waf. Te dan una pista del vendor, y cada vendor tiene bypasses documentados.
Saber qué WAF hay delante te ahorra horas: orientas las técnicas a sus puntos ciegos conocidos en lugar de probar a ciegas.
Técnicas de bypass (con XSS y SQLi)
No hay una bala de plata: se combina y se itera. Estas son las familias que más funcionan.
1. Encoding y doble encoding
Muchas reglas buscan la cadena literal. Codifícala y quizá la regla no la vea, pero el servidor la decodifica antes de usarla:
Original: <script>
URL enc: %3Cscript%3E
Doble enc: %253Cscript%253E
HTML enc: <script> (según contexto)
Para SQLi, el URL-encoding de caracteres clave o el uso de codificación hexadecimal de cadenas es un recurso habitual.
2. Alternancia de mayúsculas (case toggling)
Si la firma busca union select en minúsculas y el motor SQL no distingue mayúsculas, alterna:
UnIoN SeLeCt password FROM users
Lo mismo con XSS: <ScRiPt> puede saltarse una regla que solo mira <script> en minúsculas.
3. Comentarios inline
En SQL, los comentarios inline de MySQL parten palabras clave que el WAF busca completas, sin romper la consulta:
UNI/**/ON SEL/**/ECT
1/**/OR/**/1=1
En XSS, insertar caracteres que el navegador tolera dentro del tag puede romper la firma sin romper la ejecución.
4. Payloads y sintaxis alternativa
La forma más robusta: no uses el payload de manual. Para XSS, si <script> está bloqueado, hay decenas de vectores con otros tags y manejadores de eventos:
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<body onpageshow=alert(1)>
Para SQLi, si OR 1=1 está filtrado, existen equivalentes lógicos y funciones alternativas que consiguen el mismo efecto. Entender la vulnerabilidad por dentro (en Academy) es lo que te permite improvisar vectores en vez de depender de una lista.
5. HTTP Parameter Pollution (HPP)
Enviar el mismo parámetro varias veces puede confundir al WAF y al back-end sobre cuál procesar. Si el WAF inspecciona la primera ocurrencia y el servidor concatena o toma la última, puedes partir la carga entre varias apariciones del parámetro y colar cada mitad por separado.
6. Chunked / manipular el cuerpo
Fragmentar el cuerpo con Transfer-Encoding: chunked, jugar con espacios, saltos de línea o el Content-Type puede impedir que el WAF reconstruya la carga tal y como la ve el back-end. Es un terreno que conecta con técnicas de desincronización como el request smuggling.
7. Espacios alternativos y normalización
Muchas firmas esperan un espacio literal entre tokens (UNION SELECT). SQL acepta otros separadores que el WAF puede no contemplar: tabuladores, saltos de línea, comentarios (/**/), o caracteres de control. En SQL también sirven paréntesis para prescindir de espacios:
UNION(SELECT(password)FROM(users))
Otra vía es la normalización unicode: si el back-end normaliza ciertos caracteres unicode a su equivalente ASCII después de que el WAF haya inspeccionado, un carácter "raro" pasa el filtro y luego se convierte en el peligroso. Lo mismo con overlong encodings o el mal manejo de bytes nulos en algunos stacks. La idea de fondo se repite: explota cualquier diferencia entre lo que ve el WAF y lo que interpreta la aplicación.
El método: iterar contra el filtro
Evadir un WAF es un proceso empírico:
- Confirma la vulnerabilidad sin el WAF de por medio si puedes (o con una carga mínima).
- Fingerprintea el WAF.
- Manda la carga estándar y observa exactamente qué bloquea (¿la palabra clave? ¿un carácter? ¿la longitud?).
- Aísla el disparador y transfórmalo con una técnica de arriba.
- Itera combinando técnicas hasta que la carga pase y siga funcionando.
- Documenta la carga mínima que evade el filtro y demuestra el impacto real.
Herramientas como Burp Intruder (para automatizar variaciones) y los tamper scripts de sqlmap (para SQLi automatizada, ver el tutorial de sqlmap) aceleran el paso 5, pero el criterio de qué probar es tuyo.
Automatizar la búsqueda de bypass
Probar decenas de transformaciones a mano es tedioso, así que se automatiza con cabeza. En Burp Intruder puedes cargar una lista de variantes de un mismo payload (mayúsculas, comentarios, encoding, sintaxis alternativa) y lanzarlas contra el parámetro, observando qué respuestas no disparan el bloqueo del WAF. La columna de longitud y código de estado te dice de un vistazo cuáles pasaron.
Para SQLi, los tamper scripts de sqlmap encadenan estas transformaciones automáticamente (--tamper=space2comment,randomcase,between), y --identify-waf orienta qué combinación probar. Para XSS, colecciones de payloads como las de PayloadsAllTheThings te dan cientos de vectores listos para iterar.
Aviso importante: automatizar bypass genera mucho ruido y puede activar rate limiting o baneos de IP. Controla la velocidad, rota si el programa lo permite y no conviertas la búsqueda en un ataque de fuerza bruta que degrade el servicio. La automatización acelera, pero el objetivo sigue siendo entender por qué una variante concreta evade el filtro, no lanzar miles a ciegas.
Por qué esto importa para tu reporte
Un fallo que el WAF bloquea con la carga de manual pero que tú demuestras explotable con un bypass vale mucho más en un reporte: pruebas que la mitigación es insuficiente y que el riesgo real persiste. Los equipos de seguridad lo valoran porque les señala que su defensa da falsa sensación de seguridad.
Y del otro lado: entender los bypasses también te enseña a defender. Un WAF es una capa, no una solución; la corrección de verdad es arreglar la vulnerabilidad en el código, no confiar en el filtro.
Preguntas frecuentes (FAQ)
¿Evadir un WAF es ilegal?
Depende del objetivo. En tus labs o en un programa de bug bounty con scope que lo permita, es una técnica legítima para demostrar que una vulnerabilidad sigue explotable. Contra un sistema sin autorización, es ilegal.
¿Un WAF bypass cuenta como vulnerabilidad reportable?
Por sí solo, normalmente no. Lo reportable es la vulnerabilidad de fondo (XSS, SQLi…); el bypass es la prueba de que el WAF no la mitiga. Un fallo explotable pese al WAF vale más porque demuestra que la defensa da falsa seguridad.
¿Existe un payload universal que evada cualquier WAF?
No. Cada WAF y cada configuración es distinta. Evadir es un proceso empírico de fingerprintear, observar qué bloquea e iterar combinando técnicas. Quien te venda un "bypass mágico" te vende humo.
¿Cómo se defiende de verdad una app frente a estos bypasses?
Arreglando la vulnerabilidad en el código: consultas parametrizadas contra SQLi, codificación de salida contextual contra XSS, validación estricta. El WAF es una capa de mitigación temporal, nunca la solución de fondo.
Cómo entrenarlo
Los bypasses no se memorizan de una lista: se entrenan entendiendo la vulnerabilidad por debajo. Cuando sabes por qué un <img onerror> ejecuta o por qué un comentario inline no rompe una consulta SQL, generar variantes es natural. Estudia la teoría de XSS y SQLi, practica en labs que replican reportes reales y sigue una ruta ordenada. El WAF bypass es la prueba de que dominas la vulnerabilidad, no un truco aislado.