Slow HTTP are application layer Denial Of Service (DoS) attacks and have a potential to knock down a server with limited resources. Because of the nature of the attack (slow speed and low volume), they are hard to detect and can cause equal damage as a high volume DDoS. In this post, I’ll share my experience with these attacks
Introduction
As explained in the WiKi, slow HTTP attacks rely on the fact that the HTTP protocol, by design, requires requests to be completely received by the server before they are processed. If an HTTP request is not complete, or if the transfer rate is very low, the server keeps its resources busy waiting for the rest of the data. If the server keeps too many resources busy, this creates a denial of service. [Source : https://github.com/shekyan/slowhttptest/wiki ]
Slow HTTP attacks are primarily of three types.
Nginx architecture
Nginx has a master process and a number of helper processes (including worker processes). Master process manages all the privileged operations whereas the worker processes do the actual work and handle the connections. Nginx’s architecture is fundamentally different from that of Apache’s. Apache spawns a blocking thread for every new connection, whereas Nginx is based on non-blocking event-driven architecture.
The diagram below summarises the flow:
This architecture provides innate prevention against Slow HTTP attacks to some extent as the worker process is not blocked on IO. It can continue to serve other requests. However, it is not full proof and depends on the Nginx configuration options as well.
Some of the common configuration options provided by Nginx to prevent such attacks are:
1) limit_req – to limit the rate of requests from one IP
2) limit_conn – to limit the number of connections from one IP
3) client_body_timeout – to close the connections with slow body
4) client_header_timeout – to close the connections with slow headers
5) send_timeout – If the client does not receive anything within this time, the connection is closed.
Conclusion
Slow HTTP attacks can be as vicious as volumetric DDoS attacks, if not dealt properly. Moreover, there are a lot of moving parts in the Nginx configuration and we need to understand them properly before making random copy/paste changes.
I also see one more fix to this problem by rejecting very low client-side receive buffer window sizes, but I’m yet to explore that path.