WAF:
qué para de verdad un firewall de aplicaciones (y qué no)
Seguridad de aplicaciones web | unfantasmaenelsistema.com
Un WAF (Web Application Firewall) se pone delante de una aplicación web y examina cada petición HTTP antes de que llegue al servidor. Se vende a menudo como la solución que «protege la web», y esa expectativa es la que causa la mayoría de los disgustos: un WAF filtra patrones de ataque conocidos, pero no entiende la lógica de tu aplicación ni corrige el fallo que hay debajo.
Este artículo explica cómo decide un WAF, los dos modelos de detección, las implementaciones más comunes (Core Rule Set, ModSecurity/Coraza, WAF de CDN), el ajuste de falsos positivos, y por qué conviene verlo como un parche temporal y no como un arreglo. El objetivo es que quien lo despliega tenga expectativas realistas de lo que gana y de lo que sigue teniendo que hacer.
Qué aprenderas en este articulo
La diferencia entre modelo negativo (firmas) y modelo positivo (lista blanca) · Qué es el OWASP Core Rule Set, los paranoia levels y el sistema de puntuación (scoring) · Modo detección frente a modo bloqueo, y cómo se afina sin romper la aplicación · Por qué un WAF se puede evadir: codificación, HTTP request smuggling, lógica de negocio · Dónde encaja de verdad: virtual patching mientras el equipo corrige el código
1. Qué mira un WAF y dónde se coloca
Un WAF opera en la capa 7: ve el método, la ruta, las cabeceras, los parámetros de la query, el cuerpo (formularios, JSON, XML) y, si termina el TLS, también el contenido cifrado. Sobre eso aplica reglas y decide: permitir, bloquear, registrar o desafiar (por ejemplo, un CAPTCHA o un JavaScript challenge).
| Modo de despliegue | Cómo se integra | Notas |
|---|---|---|
| Proxy inverso | El WAF recibe todo el tráfico y lo reenvía al backend | El más común; termina TLS; punto único que hay que dimensionar |
| Módulo en el servidor web | ModSecurity/Coraza embebido en Nginx, Apache o IIS | Sin salto de red extra; comparte recursos con el servidor |
| WAF de CDN / nube | El tráfico ya pasa por el CDN (Cloudflare, Akamai, AWS, Azure, Fastly) | Despliegue inmediato; reglas gestionadas; menos control fino |
| Sidecar / servicio en malla | Un contenedor WAF junto a cada servicio (Coraza, Envoy) | Encaja en Kubernetes; política por servicio |
Colocarlo bien importa: si el WAF no ve la IP de origen real (porque hay otro proxy delante), el rate limiting y las reglas por reputación dejan de funcionar. Hay que propagar y confiar en `X-Forwarded-For` solo desde los saltos conocidos.
2. Modelo negativo y modelo positivo
| Modelo | Cómo decide | Fuerte en | Débil en |
|---|---|---|---|
| Negativo (blocklist / firmas) | Bloquea lo que coincide con patrones de ataque conocidos (SQLi, XSS, traversal, RCE) | Despliegue rápido, cubre ataques genéricos y escáneres automáticos | Falsos positivos; evasión por variantes nuevas o por codificación |
| Positivo (allowlist) | Solo permite peticiones que encajan en un modelo de lo que la app espera (rutas, parámetros, tipos, longitudes) | Muy efectivo, incluso contra ataques desconocidos | Costoso de construir y de mantener; cada cambio de la app obliga a actualizarlo |
En la práctica casi todos los despliegues empiezan (y se quedan) en modelo negativo, porque el positivo exige conocer la aplicación al detalle. Un punto intermedio útil es aprender el modelo positivo de forma automática a partir de tráfico legítimo observado, y aplicarlo solo a las rutas más sensibles (login, pagos, APIs internas).
3. El OWASP Core Rule Set
El OWASP Core Rule Set (CRS) es el conjunto de reglas de modelo negativo más usado. Es libre, funciona sobre ModSecurity y sobre Coraza, y muchos WAF comerciales lo llevan por dentro con otro nombre. Dos conceptos definen cómo se comporta:
- Paranoia levels (PL1 a PL4). A más nivel, más reglas y más estrictas. PL1 es el punto de partida razonable para la mayoría de sitios; PL3-PL4 solo para aplicaciones que toleran restricciones fuertes (banca, sector público) y con mucho trabajo de tuning
- Anomaly scoring. Cada regla que dispara suma puntos a la petición en lugar de bloquearla de inmediato. Si el total supera un umbral (por defecto 5 en entrada), se bloquea. Esto evita que una sola coincidencia dudosa tumbe tráfico legítimo y da una señal graduada
# CRS: bajar el umbral hace el WAF mas estricto; subirlo, mas permisivo SecAction "id:900110, phase:1, nolog, pass, \ setvar:tx.inbound_anomaly_score_threshold=5, \ setvar:tx.outbound_anomaly_score_threshold=4" # Empezar SIEMPRE en modo solo-deteccion para medir falsos positivos SecRuleEngine DetectionOnly # Excluir una regla concreta para una ruta concreta (tras confirmar que es FP) SecRule REQUEST_URI "@beginsWith /api/reports" \ "id:1001, phase:1, pass, nolog, ctl:ruleRemoveById=942100"
El orden correcto: detección primero, bloqueo después
Arrancar un WAF directamente en modo bloqueo sobre una aplicación en producción es la forma más rápida de generar una incidencia: reglas de SQLi que chocan con campos de texto libre, reglas de XSS que rompen un editor enriquecido, reglas de protocolo que cortan una API legítima · El flujo sano: modo detección durante días o semanas, revisar cada regla que dispara, crear exclusiones justificadas, y solo entonces pasar a bloqueo, primero en una parte del tráfico
4. Falsos positivos y tuning
El coste real de un WAF no es la licencia ni el hardware: es el tiempo de ajuste. Un WAF sin mantener acaba en uno de dos estados, y los dos son malos: tan estricto que la gente pide excepciones a todo, o tan relajado que no aporta.
| Situación | Causa habitual | Ajuste |
|---|---|---|
| Bloqueos en formularios de texto libre | Reglas de SQLi/XSS que ven comillas, corchetes o palabras clave en contenido legítimo | Exclusión por parámetro y por ruta; subir umbral solo en esa ruta; nunca desactivar la regla globalmente |
| APIs que devuelven 403 tras un cambio de esquema | El WAF valida content-type, longitudes o campos que ya no encajan | Actualizar el modelo/allowlist con cada release; integrarlo en el pipeline |
| Falsos negativos en un endpoint nuevo | La ruta no estaba cuando se hizo el tuning | Revisión periódica; alertas cuando aparece tráfico a rutas no perfiladas |
| Subida de ficheros bloqueada o no inspeccionada | Límite de tamaño de cuerpo, o el WAF no mira multipart | Ajustar SecRequestBodyLimit con criterio; escanear el fichero aparte (AV/sandbox) |
- Trata las reglas del WAF como código: en control de versiones, con revisión de cambios y con un entorno de pruebas donde repites tráfico real antes de tocar producción
- Mide: número de bloqueos por regla, top de rutas y parámetros que disparan, ratio detección/bloqueo. Sin métricas, el tuning es a ciegas
- Documenta cada exclusión con el motivo y la fecha; revísalas cuando la aplicación cambie
5. Por qué un WAF se evade
Un WAF de modelo negativo inspecciona una representación del tráfico; si el atacante consigue que el servidor interprete la petición de forma distinta a como la vio el WAF, la regla no aplica. Las familias clásicas:
- Codificación y ofuscación. Doble URL-encoding, entidades HTML, comentarios intercalados, mayúsculas/minúsculas alternadas, notación alternativa. El CRS normaliza mucho, pero es una carrera constante
- HTTP request smuggling / desync. Discrepancias entre cómo el WAF (o un proxy intermedio) y el backend interpretan `Content-Length` y `Transfer-Encoding` permiten «colar» una petición que el WAF no llega a ver entera
- Parámetros duplicados y HTTP Parameter Pollution. El WAF evalúa una copia del parámetro y el backend usa otra
- Lógica de negocio. Un WAF no sabe que un usuario no debería poder cambiar el `account_id` de otra persona, ni que 10.000 peticiones de «consultar saldo» en un minuto son un abuso: eso es IDOR y abuso funcional, invisibles para las firmas
- Canales que no ve. Ataques contra un endpoint interno, contra la cola de mensajes, o a través de una dependencia: el WAF solo mira la puerta de entrada HTTP
Probar la evasión de un WAF: solo con autorización
Comprobar si tu propio WAF bloquea lo que debe, en un entorno de pruebas o dentro de un pentest con alcance firmado, es una actividad legítima y recomendable · Lanzar técnicas de evasión (smuggling, payloads ofuscados, fuzzing) contra un WAF o una aplicación de terceros sin permiso escrito puede constituir un delito de acceso no autorizado o de daños (en España, arts. 197 bis, 197 ter y 264 del Código Penal) · Para practicar: OWASP Juice Shop o DVWA detrás de ModSecurity/Coraza con el CRS, o los laboratorios de la propia comunidad CRS (ftw / go-ftw test framework)
6. Dónde encaja de verdad: virtual patching
El uso donde un WAF brilla es el parcheo virtual: cuando se publica una vulnerabilidad en una librería o en tu propio código y el arreglo va a tardar (hay que probar, hay ventana de despliegue, el proveedor no ha sacado parche), una regla específica en el WAF puede bloquear el patrón exacto de explotación mientras tanto.
- Es rápido de aplicar y rápido de revertir, y se puede acotar a una ruta y un parámetro concretos, con lo que el riesgo de falso positivo es bajo
- Es temporal por definición: la regla lleva fecha de caducidad y un ticket que la ata al arreglo real en el código. Un parche virtual que lleva dos años puesto es deuda técnica disfrazada de seguridad
- Funcionó a gran escala con vulnerabilidades muy explotadas: mientras los equipos actualizaban, una regla de WAF frenaba el patrón de ataque más común
Recursos
OWASP CRS — documentación, paranoia levels y guía de tuning (coreruleset.org) · ModSecurity Handbook y la documentación de Coraza (WAF en Go, sucesor natural) · OWASP CRS ‘go-ftw’ — framework para escribir tests de reglas y evitar regresiones · Guías de WAF de tu CDN (Cloudflare, AWS WAF, Azure Front Door) para las reglas gestionadas · Nuestros artículos de cabeceras de seguridad HTTP y del OWASP Top 10 para el contexto
Conclusión
Un WAF es una capa útil: filtra el ruido de fondo de internet, frena escáneres y exploits genéricos, y da un botón rápido para contener una vulnerabilidad concreta mientras se corrige. En modo scoring y bien afinado, ese valor es real.
Lo que no es, es un sustituto de escribir código seguro. No entiende tu lógica de negocio, se puede evadir con discrepancias de interpretación, y no ve nada que no pase por su puerta HTTP. La forma sana de desplegarlo: empezar en detección, afinar con métricas, pasar a bloqueo por fases, y tratar cada regla de contención como un parche con fecha de caducidad atada al arreglo de verdad.
unfantasmaenelsistema.com | Seguridad, sistemas y todo lo que no debería funcionar (pero funciona)

