El ataque HTTP Slow Read (también llamado Slow Read DoS) es una técnica de denegación de servicio low-and-slow en la que el cliente envía un request HTTP completo y válido, pero luego anuncia una ventana de recepción TCP artificialmente pequeña, forzando al servidor a transmitir su respuesta un fragmento diminuto a la vez y a mantener la conexión —y su buffer de envío— abierta durante un periodo extendido. A diferencia de los ataques que estancan un request, Slow Read estanca la respuesta, agotando buffers de envío del lado del servidor y slots de conexión en lugar de CPU o ancho de banda.
Resumen rápido — Después de que un request normal se completa, el atacante fija su ventana de recepción TCP anunciada a un valor cercano a cero (tan bajo como 1 byte), lo que fuerza al stack TCP del servidor a obedecer el control de flujo y enviar datos en trozos minúsculos, enviando TCP Window Probes periódicos para verificar si la ventana se abrió. El buffer de envío del servidor se mantiene lleno y la conexión permanece abierta mucho más de lo que tomaría una respuesta normal, y hacer esto en muchas conexiones paralelas agota los buffers de envío, slots de conexión o worker threads disponibles. La mitigación requiere timeouts del lado de la respuesta (
send_timeout), aplicación de un throughput mínimo, pisos de ventana a nivel TCP, y terminar las conexiones en una capa edge o proxy reverso que pueda absorber la entrega lenta de respuesta sin ocupar el origen.
Última actualización: 2026-08-08
Contexto: una variante del lado de la respuesta de low-and-slow
Los ataques Slow Read surgieron cuando investigadores de seguridad y autores de herramientas de pentest (slowhttptest es la implementación pública más usada) extendieron la familia de ataques low-and-slow más allá de técnicas del lado del request como Slowloris y R.U.D.Y. Donde esos ataques explotan la ambigüedad de cuándo se considera completo un request HTTP, Slow Read explota un mecanismo de la capa de transporte —el control de flujo TCP— que no tiene nada que ver con el framing de requests HTTP. Funciona contra cualquier servidor HTTP que corra sobre un stack TCP estándar, porque la vulnerabilidad es un comportamiento normal y conforme a la especificación del propio TCP, no un bug.
Este artículo asume familiaridad con la categoría general de ataque low-and-slow y se enfoca específicamente en el mecanismo de la ventana de recepción. Para técnicas low-and-slow del lado del request, consulta ¿Qué es un ataque Slowloris?.
Cómo funciona normalmente la ventana de recepción TCP
Cada segmento TCP lleva un campo Window Size que le indica al emisor cuántos bytes de datos no confirmados está dispuesto a aceptar el receptor en su buffer de recepción en ese momento. Este es el mecanismo integrado de control de flujo de TCP, definido en RFC 793 y refinado por el escalado de ventana (RFC 7323): existe para evitar que un emisor rápido desborde el buffer de un receptor lento.
Intercambio normal:Cliente → Servidor: request HTTP GET (completo)Servidor internamente: prepara una respuesta de 500 KBStack TCP del cliente: anuncia Window Size = 65,535 (o más grande con escalado de ventana)Servidor → Cliente: envía la respuesta en segmentos grandes, limitado solo por MSS y control de congestiónEl cliente confirma con prontitud, la ventana se mantiene abiertaLa conexión se completa en milisegundos a segundos bajosUn cliente con una conexión saludable y de alto ancho de banda anuncia una ventana grande (decenas de kilobytes, o megabytes con escalado de ventana habilitado) y la transferencia procede a una velocidad cercana a la línea.
Cómo manipula la ventana el ataque
Los ataques Slow Read abusan del hecho de que un receptor está totalmente facultado, bajo la especificación TCP, para anunciar una ventana arbitrariamente pequeña; no hay un mínimo exigido por el protocolo.
Ataque Slow Read:Paso 1: El atacante envía un request HTTP completo y sintácticamente válidoPaso 2: El servidor comienza a preparar la respuesta (ej. una página o archivo de 500 KB)Paso 3: El stack TCP del atacante anuncia Window Size = 1 (u otro valor cercano a cero) en lugar del 65,535+ normalPaso 4: El stack TCP del servidor, respetando el control de flujo, puede enviar como máximo 1 byte antes de que deba detenerse y esperar un ACK que abra más la ventanaServidor → Cliente: se envía 1 byteCliente → Servidor: ACK, Window Size = 1 (todavía cercano a cero)Servidor → Cliente: se envía 1 byte más[se repite durante toda la longitud de la respuesta]Paso 5: El buffer de envío del servidor —típicamente 64 KB-128 KB— se llena porque los datos no pueden salir del buffer tan rápido como la aplicación escribe en élPaso 6: El servidor comienza a enviar TCP Window Probes (también llamados sondeos de ventana cero) — paquetes pequeños que preguntan "¿ya se abrió tu ventana?" Cada sondeo consume ciclos de CPU y mantiene activo el estado de conexión del kernelPaso 7: Repetido en docenas a cientos de conexiones paralelas, se agota el pool de buffers de envío, slots de conexión, o worker threads/procesos del servidorEl atacante puede además combinar una ventana pequeña con una cadencia de ACK lenta, estirando aún más cuánto tiempo ocupa cada conexión los recursos del servidor. Como cada paquete intercambiado es un segmento TCP completamente válido, no hay nada que un filtro de paquetes basado en firmas pueda marcar.
Qué hace distinto a Slow Read: agotamiento del buffer de envío, no estancamiento del lado de recepción
La distinción técnica crítica entre Slow Read y los ataques que estancan el request como Slowloris es qué lado de la conexión se está privando:
- En Slowloris, el servidor está esperando recibir datos (el resto de los headers del request) que nunca llegan. El recurso agotado típicamente es un worker thread/proceso esperando en un estado de lectura.
- En Slow Read, el servidor ya recibió el request completo y está intentando enviar una respuesta, pero la ventana anunciada por el cliente evita que los datos salgan del buffer de envío del servidor a cualquier tasa razonable. El recurso agotado es el propio buffer de envío, más cualquier slot de conexión o thread que permanezca asignado mientras el envío está en progreso.
Esto significa que Slow Read es efectivo incluso contra servidores cuyos timeouts del lado del request (RequestReadTimeout, client_header_timeout) ya están reforzados contra Slowloris; esos ajustes rigen cuánto tiempo espera el servidor para recibir datos, no cuánto tiempo se le permite gastar enviando una respuesta. Un servidor reforzado solo contra ataques low-and-slow del lado del request puede permanecer completamente expuesto a Slow Read a menos que se configuren timeouts del lado de la respuesta por separado.
Slowloris vs. HTTP Slow Read vs. RUDY
| Característica | Slowloris | HTTP Slow Read | R.U.D.Y. |
|---|---|---|---|
| Fase HTTP objetivo | Headers del request | Entrega del cuerpo de la respuesta | Cuerpo del request (POST) |
| Mecanismo | Nunca envía CRLF CRLF | Ventana de recepción TCP cercana a cero | 1 byte de cuerpo POST por intervalo |
| Recurso agotado | Worker thread esperando recibir | Buffer de envío + slot de conexión | Worker thread esperando recibir el cuerpo |
| Requiere que exista una respuesta | No — el request nunca se completa | Sí — el servidor debe tener datos para enviar | No — el request nunca se completa |
| Manipulación a nivel TCP | Ninguna | Central (campo de tamaño de ventana) | Ninguna |
| Efectivo contra servido de archivos estáticos | Limitado (sin headers que retener en un GET sin cuerpo) | Sí — cualquier respuesta, incluyendo assets estáticos | No — necesita un endpoint POST |
Detectable solo vía RequestReadTimeout/timeout de headers | Sí | No — opera después de recibir headers/cuerpo | Parcialmente |
| Herramienta típica | slowloris.pl y derivados | slowhttptest -g -o slow_read_stats.csv -X | r-u-dead-yet, OWASP DOS HTTP POST |
Slow Read es posiblemente más amplio en alcance que Slowloris porque puede apuntar a cualquier endpoint que devuelva un cuerpo de respuesta no trivial, incluyendo assets estáticos como imágenes o bundles de JS, mientras que Slowloris y R.U.D.Y. dependen de fases específicas del request (headers, o un cuerpo POST) que no todo request tiene.
Notas de exposición del lado del servidor
| Servidor / preocupación | Exposición | Por qué |
|---|---|---|
Servidores sin send_timeout/timeout de respuesta configurado | Alta | Nada acota cuánto tiempo puede ocupar una conexión un envío lento |
| Servidores thread/proceso-por-conexión (Apache Prefork/Worker, IIS más antiguo) | Alta | Cada envío lento fija un worker completo durante su duración |
| Servidores asíncronos/orientados a eventos (nginx, LiteSpeed) | Media | No bloquea un thread, pero los buffers de envío y tablas de conexión siguen siendo finitos |
| Servidores que sirven archivos estáticos grandes o respuestas sin comprimir | Mayor | Más bytes de respuesta significa más tiempo que un atacante puede estirar el envío |
| Servidores detrás de un proxy reverso o red edge con buffering | Baja | El proxy/edge recibe la respuesta completa rápidamente del origen y pacea la entrega al cliente lento de forma independiente, liberando la conexión del origen casi de inmediato |
Señales de detección y telemetría
Como otras técnicas low-and-slow, Slow Read produce casi ninguna señal volumétrica, pero deja trazas específicas a nivel de TCP y estado de conexión.
# Busca conexiones atascadas en un estado de "envío" por un tiempo inusualmente largoss -o state established '( dport = :80 or dport = :443 )' -i | grep -i "send"
# Captura e inspecciona los tamaños de ventana anunciados — una ventana cercana a# cero sostenida es la firma directa de este ataquetcpdump -i eth0 'tcp port 443' -nn -v | grep -i "win 0\|win 1\b"
# Verifica actividad de TCP Window Probe / ventana cero en contadores del kernelnstat -az | grep -i "zerowindow\|probe"
# nginx: conexiones estancadas en estado "writing" más de lo esperadonginx -T | grep send_timeout| Indicador | Normal | Bajo Slow Read |
|---|---|---|
| Ventana TCP anunciada por el cliente | Decenas de KB o más (con escalado) | Cercana a cero (1-64 bytes), sostenida |
| Paquetes de TCP Window Probe / ventana cero | Raros, transitorios | Frecuentes y sostenidos por conexión |
| Duración de conexión para un tamaño de respuesta dado | Proporcional al tamaño y ancho de banda normal | Órdenes de magnitud más larga de lo esperado |
| Utilización del buffer de envío del servidor | Fluctúa con la carga | Saturado, sin drenar |
| Ancho de banda usado por el cliente atacante | N/A | Cercano a cero |
| CPU por procesamiento de sondeo/retransmisión | Base | Elevada en relación con el volumen de tráfico |
Técnicas de mitigación
1. Aplicar timeouts del lado de la respuesta, no solo del lado del request
Reforzar RequestReadTimeout o client_header_timeout por sí solo no hace nada contra Slow Read, ya que el request ya se recibió por completo. Se necesita un timeout separado que acote cuánto tiempo se permite que tarde el envío de una respuesta.
# nginx — acota el tiempo entre escrituras sucesivas al clientesend_timeout 10s;# Apache — mod_reqtimeout también soporta un límite adyacente a la fase de# escritura vía las directivas keepalive y Timeout estándar; combínalo con un# proxy reverso/upstream para una aplicación más fuerte del lado de la respuestaTimeout 202. Aplicar un throughput mínimo efectivo, no solo un timeout
Un timeout fijo todavía puede permitir que un atacante gotee justo los datos suficientes para evitar activarlo. Donde esté soportado, aplica una tasa mínima de bytes/seg para los datos salientes, replicando el enfoque MinRate usado contra Slowloris del lado del request.
3. Establecer un piso en la ventana TCP aceptada, donde la plataforma lo permita
Algunos load balancers y proxies reversos permiten configurar un tamaño mínimo de ventana que respetarán de un cliente, rechazando efectivamente que un peer estanque una conexión por debajo de cierto piso de throughput. Esto está menos comúnmente expuesto que los timeouts a nivel de aplicación, pero donde está disponible neutraliza directamente el mecanismo.
4. Limitar conexiones concurrentes de envío lento por IP
limit_conn_zone $binary_remote_addr zone=perip:10m;limit_conn perip 20;Capping concurrent connections per source limits how many send buffers a single attacker can occupy simultaneously, regardless of how long each one is held.
5. Terminar y hacer buffer de las respuestas en una capa de proxy reverso o edge
La mitigación estructuralmente más efectiva separa la generación de la respuesta del origen de la entrega lenta al cliente. Un proxy reverso o nodo edge recibe la respuesta completa del origen a velocidad normal, libera la conexión del origen casi de inmediato, y luego pacea la entrega al cliente lento de forma independiente usando su propio pool de conexiones y buffers, diseñado para absorber muchas entregas lentas concurrentes sin ocupar la capacidad del backend.
6. Servir respuestas grandes o costosas a través de una capa de CDN/caché
Las respuestas servidas desde una caché en el edge nunca tocan el buffer de envío del origen para un request dado en absoluto, lo que elimina por completo al origen de la superficie de ataque para el contenido cacheado.
Errores comunes
| Error | Por qué falla | Mejor enfoque |
|---|---|---|
Asumir que las mitigaciones de Slowloris (RequestReadTimeout, client_header_timeout) también detienen Slow Read | Esos acotan la recepción del request, no la entrega de la respuesta | Configura send_timeout / timeouts de fase de respuesta por separado |
| Monitorear solo el volumen de tráfico entrante | La firma de Slow Read está en el campo de ventana TCP saliente, no en el volumen entrante | Inspecciona los tamaños de ventana anunciados y los contadores de sondeo de ventana cero |
| Tratar una ventana TCP pequeña como inherentemente maliciosa | Clientes reales en redes restringidas o con pérdida pueden anunciar legítimamente ventanas pequeñas brevemente | Combina las señales de tamaño de ventana con duración de conexión y concurrencia por IP antes de bloquear |
| Servir respuestas grandes sin comprimir sin una capa de buffering al frente | Respuestas más grandes le dan al atacante más tiempo para estirar la ventana de exploit por conexión | Comprime las respuestas, cachea lo que se pueda cachear, y hace buffer de la entrega en una capa de proxy/edge |
| Ignorar las conexiones del lado de la respuesta en la planeación de capacidad | El agotamiento de buffer de envío y slot de conexión puede ocurrir incluso con las defensas del lado del request completamente reforzadas | Incluye las conexiones con respuesta en vuelo en las pruebas de carga y capacidad |
Cómo implementarlo con Azion
Azion se ubica entre el cliente y el origen, lo que cambia quién absorbe realmente una entrega de respuesta con ventana lenta.
- Firewall puede aplicar límites de conexión concurrente por IP que reducen cuántas sesiones de slow-read puede mantener abiertas a la vez un solo origen
- WAF puede ayudar a aplicar reglas conductuales contra patrones de conexión consistentes con abuso de respuesta lenta, dependiendo de los conjuntos de reglas configurados
- DDoS Protection brinda detección siempre activa orientada a patrones de agotamiento de conexión en Capa 7, incluyendo técnicas low-and-slow
- Cache puede servir respuestas elegibles directamente desde el edge, lo que elimina el buffer de envío del origen de la superficie de ataque para contenido cacheado
- WAAP combina estos controles para equipos que quieren WAF, protección DDoS y defensas relacionadas en capas
Como el edge recibe una respuesta del origen rápidamente y luego pacea la entrega a un cliente lento de forma independiente, un atacante que manipula la ventana de recepción TCP generalmente ocupa capacidad del lado del edge —construida para alta concurrencia de conexiones— en lugar de recursos del origen.
Recursos relacionados
- Ataques Low and Slow
- ¿Qué es un ataque Slowloris?
- ¿Qué es un ataque DDoS?
- ¿Qué es SYN Flood?
- Azion WAF
- Azion DDoS Protection
Preguntas frecuentes
¿Qué es un ataque HTTP Slow Read? Un ataque HTTP Slow Read envía un request HTTP completo y válido y luego anuncia una ventana de recepción TCP artificialmente pequeña, forzando al servidor a enviar su respuesta en fragmentos diminutos y a mantener la conexión —y su buffer de envío— abierta mucho más de lo que tomaría una transferencia normal. Agota buffers de envío y slots de conexión en lugar de ancho de banda o CPU.
¿Qué es la ventana de recepción TCP y por qué la manipula el ataque? La ventana de recepción TCP es un campo en cada segmento TCP que le indica al emisor cuántos bytes de datos no confirmados está dispuesto a aceptar el receptor en ese momento. El diseño de control de flujo de TCP exige que el emisor la respete, así que un receptor que anuncia una ventana cercana a cero fuerza al emisor —el servidor— a transmitir datos un fragmento diminuto a la vez, que es exactamente el apalancamiento que usa el ataque.
¿En qué se diferencia HTTP Slow Read de Slowloris? Slowloris estanca el request al nunca enviar la secuencia CRLF CRLF que termina los headers, así que el servidor se queda esperando recibir datos. Slow Read permite que el request se complete normalmente y en cambio estanca la respuesta manipulando la ventana de recepción TCP, así que el servidor se queda sin poder enviar datos que ya preparó. Atacan mitades opuestas del ciclo request/response y requieren mitigación distinta.
¿Reforzar las defensas de Slowloris también detiene Slow Read? No. Los timeouts del lado del request como RequestReadTimeout de Apache o client_header_timeout de nginx acotan cuánto tiempo espera el servidor para recibir un request, lo que no tiene efecto una vez que un request ya se completó y el servidor pasó a enviar una respuesta. Slow Read requiere timeouts separados del lado de la respuesta, como send_timeout.
¿Qué es un TCP Window Probe? Un TCP Window Probe (también llamado sondeo de ventana cero) es un paquete pequeño que un emisor transmite periódicamente para verificar si la ventana previamente anunciada cerca de cero de un receptor se ha abierto lo suficiente para reanudar el envío de datos. Sondeos de ventana frecuentes y sostenidos en muchas conexiones son una señal fuerte de un ataque Slow Read en curso, ya que las condiciones legítimas de ventana cero normalmente son breves.
¿Slow Read puede atacar contenido estático como imágenes o archivos JavaScript? Sí. Como Slow Read solo requiere que el servidor tenga algún cuerpo de respuesta que enviar, puede apuntar a cualquier endpoint que devuelva un payload no trivial, incluyendo assets estáticos. Esto lo hace más amplio en alcance aplicable que Slowloris o R.U.D.Y., que dependen de fases específicas del request como headers o un cuerpo POST.
¿Comprimir las respuestas ayuda contra Slow Read? Puede ayudar algo al reducir el total de bytes que el servidor debe empujar a través de una ventana restringida, lo que acorta cuánto tiempo se puede estirar cada conexión para una pieza dada de contenido. No elimina el ataque, ya que incluso una respuesta pequeña comprimida todavía puede enviarse un byte a la vez si la ventana permanece cerca de cero.
¿Una ventana TCP anunciada pequeña siempre es evidencia de un ataque? No. Clientes en redes genuinamente restringidas, congestionadas o con pérdida pueden anunciar legítimamente una ventana pequeña por periodos breves como parte del control de flujo TCP normal. La señal distintiva es una ventana cercana a cero sostenida combinada con una conexión inusualmente longeva y, a menudo, muchas conexiones similares concentradas en pocas IP de origen.
¿Usar una CDN o caché edge reduce la exposición a Slow Read? Sí, para contenido cacheable. Si una respuesta se puede servir directamente desde una caché edge, el servidor de origen nunca tiene que mantener un buffer de envío abierto para ese request en absoluto; la entrega lenta, si ocurre, sucede entre el edge y el cliente, usando capacidad del lado del edge construida para manejar muchas conexiones lentas concurrentes.
¿Qué herramienta se usa comúnmente para probar o demostrar Slow Read? slowhttptest es la herramienta open-source más usada para probar técnicas low-and-slow, incluyendo Slow Read vía su modo -g -o slow_read_stats.csv -X, que simula clientes que anuncian una ventana de recepción pequeña contra un servidor objetivo con fines de prueba autorizada.
¿Un proxy reverso puede neutralizar por completo Slow Read en el origen? Un proxy reverso con buffering correctamente configurado reduce sustancialmente la exposición: puede recibir la respuesta completa del origen rápidamente, liberar la conexión del origen, y luego pacear la entrega lenta al cliente de forma independiente usando sus propios recursos. Esto no elimina el ataque en abstracto, pero mueve el costo de recursos del origen a la capa de proxy/edge, que típicamente está construida con mucho más margen de concurrencia de conexiones.
Fuentes
- IETF. “Transmission Control Protocol.” RFC 793.
- IETF. “TCP Extensions for High Performance.” RFC 7323 (escalado de ventana).
- IETF. “HTTP Semantics.” RFC 9110.
- OWASP. “Denial of Service Cheat Sheet.”
- NIST. “Guide to Intrusion Detection and Prevention Systems.” SP 800-94.
- nginx. “Module ngx_http_core_module: send_timeout.” Documentación oficial.