← Blog
// RED TEAM · WEB

Cómo se evade un WAF (y por qué un blocklist casi nunca basta)

Publicado el 12 ago 2026 · 8 min de lectura
Red TeamWebWAFEvasión

«Tenemos un WAF» tranquiliza a mucha gente más de lo que debería. Un Web Application Firewall bien puesto detiene el ruido y a los escáneres automáticos, pero la mayoría funcionan por lista negra: bloquean cadenas «malas conocidas». Y una lista negra persigue texto, no intención. Como hay infinitas formas de escribir el mismo ataque, casi siempre hay una que la lista no contempla.

Qué es (y qué no es) un WAF

Un WAF inspecciona las peticiones y bloquea las que casan con sus reglas. Hay dos filosofías: lista negra (denegar lo malo conocido — la mayoría) y lista blanca / seguridad positiva (permitir solo lo esperado — más segura, más difícil de mantener). La lista negra es un badén: te frena, no te para. Estas son las cuatro evasiones que se ven una y otra vez.

1. El mismo ataque, otra forma (XSS sin <script>)

El error clásico: bloquear <script> y creer que has parado el XSS. Pero JavaScript se ejecuta de muchas maneras. Un atributo on… en cualquier etiqueta vale igual:

Bloqueado:  <script>alert(1)</script>
Pasa:       <img src=x onerror=alert(1)>
Pasa:       <svg onload=alert(1)>

La regla perseguía una etiqueta concreta; el ataque (ejecutar JS) tiene decenas de vías.

2. Codificar lo prohibido (path traversal)

El WAF bloquea ../ en claro, pero el servidor decodifica %XX antes de usar la ruta. Si codificas los puntos y las barras, el filtro no ve el patrón y el servidor sí lo reconstruye:

Bloqueado:  ../../etc/passwd
Pasa:       %2e%2e%2f%2e%2e%2fetc%2fpasswd

La misma idea sirve para colar caracteres «prohibidos» en casi cualquier parámetro.

3. Romper el patrón (mayúsculas, comentarios, sin espacios)

Muchas reglas de SQLi son ingenuas: buscan or en minúscula con espacios, o la palabra UNION. Se rompen cambiando la forma sin cambiar el significado:

Bloqueado:  ' OR 1=1 --
Pasa:       '/**/OR/**/1=1        (comentarios en línea como separador)
Pasa:       'oR'1'='1'            (sin espacios, comparación de cadenas)

Mayúsculas alternadas, comentarios /**/, tabuladores en vez de espacios… todo apunta a lo mismo: el motor SQL es tolerante; el filtro, literal.

4. Doble codificación (contra el WAF «listo»)

Algunos WAF decodifican una vez y luego filtran. La respuesta es codificar dos veces: el WAF ve una capa limpia y la aplicación, al decodificar de nuevo, revela el ataque.

%3C          -> "<"            (una capa: el WAF lo bloquea)
%253C        -> "%3C" -> "<"    (dos capas: el WAF ve %3C, la app ve <)
🧱 Las cuatro las puedes practicar en el WAF Bypass Lab: cuatro niveles donde escribes el payload y el motor te dice si pasa el filtro y cumple el objetivo. Para generar variantes de un payload cualquiera, el mutador WAF Bypass; y para entender el ángulo de codificación, «encoding no es cifrado».

Por qué siempre hay un hueco

Porque una lista negra intenta enumerar lo infinito. El ataque es una intención (ejecutar JS, leer un fichero, alterar una query); las representaciones de esa intención son incontables (codificaciones, mayúsculas, comentarios, caracteres alternativos, fragmentación…). El defensor tiene que acertar todas; el atacante, solo una.

⚠️ El WAF no es el arreglo, es una capa. Si tu única defensa contra el SQLi es el WAF, tienes SQLi. El WAF compra tiempo (virtual patching, frena escáneres, bloquea lo evidente), no cierra el agujero.

Lo que sí cierra el agujero

Checklist

Un WAF es un buen guardia en la puerta, pero no repara la cerradura rota de dentro. Úsalo como lo que es —una capa— y arregla el fallo donde de verdad vive: en el código.

Comparte: LinkedIn X
Sergio Belmonte Morales
Sergio Belmonte Morales
Analista de Ciberseguridad · SOC · Especialista en Sentinel/KQL