Mitigating Slow HTTP Post DDoS Attacks With iRules

This past week researchers demonstrated a new HTTP DDoS attack in which a slow POST request will result in leaving a connection open longer than necessary. The heart of the attack relies on sending a POST request with given “content-length” then very slowly sending the POST message body to the server. The server will leave the connection open as it continues to receive data. If a large number of these requests are executed against a server, there is potential for exhausting the connection table leaving the server unable to respond to further requests.

There are a few different ways to mitigate such an attack using iRules. You could build a list of all the URLs that require POST requests and only allow requests for these URLs. This method while effective against a blanket attack would prove ineffective against an attacker who was targeting a page that relies on legitimate POST requests. Aside from that, someone must maintain the list. Enter the “after” command…

The after command was introduced in version 10 of BIG-IP and allows among other things, the cancellation of a previous script. In this example, if our client is sending their POST request too slowly we will instruct our BIG-IP to send them a HTTP 500 error and close the connection after a given period. If their request is received within the allotted time period, we will cancel our previous instruction and allow the connection to them proceed to the origin servers.

   1: rule block_slow_post_requests {
   2: when HTTP_REQUEST {
   3:     if { [HTTP::method] equals "POST"} {
   4:         # If the entire request hasn't been received within 10 seconds, send a 500, and close the conneciton
   5:         set id [after 10000 { 
   6:             HTTP::respond 500 content "Your POST request is not being received quickly enough. Please retry." 
   7:             TCP::close 
   8:         }]
   9:         HTTP::collect [HTTP::header Content-Length]
  10:     }
  11: }
  12:  
  13: when HTTP_REQUEST_DATA {
  14:     if {[info exists id]} {
  15:         # If all the POST data has been received, load balancing will be selected at which point cancel the connection closure
  16:         after cancel $id
  17:     }
  18: }
  19: }

This iRule will stop the attack described here, but there is at least one case where it might not be appropriate for your environment. iRules have a hard memory limit of 4 MB. If your site relies on large data transfers via POST requests, this iRule will break things. This won’t apply to vast majority of deployments, but is worth mentioning.

This rather simple snippet of code can prove very powerful in mitigating an attack of this nature. This barrier combined with LTM’s adaptive reaping abilities will provide insulation from your origin servers being attacked with this HTTP vulnerability. The ability to protect an entire farm of web servers from one strategic point of control provides great agility for an engineer’s response to a threat. We hope this helps you in protecting your organization’s application from this subtle, but equally crippling DDoS attack.

Published Nov 05, 2010
Version 1.0

Was this article helpful?

3 Comments

  • Is there any way to be alerted or generate a log message when an iRule like this gets tripped?
  • George_Watkins_'s avatar
    George_Watkins_
    Historic F5 Account
    Hi cweeklund,

     

     

    Add a log statement before the TCP::close action. Something like this should work:

     

     

    log local0. "Slow post detected from [IP::addr]. Connection closed."
  • Here's a link to the updated version of the iRule:

     

     

    https://devcentral.f5.com/s/articles/mitigating-slow-http-post-ddos-attacks-with-irules-ndash-follow-up

     

     

    Aaron