iRule Security 101 - #01 - HTTP Version

When looking at securing up your web application, there are a set of fairly standard attack patterns that application firewalls make use of to protect against those bad guys out there who are trying exploit your website.  A good reference for web application attacks is the Open Web Application Security Project (OWASP). In this series of tech tips, I'm going to highlight different attacks and how they can be defended against by using iRules.

In the first installment of this series I will show how to only allow valid HTTP requests to your application server.  The most common HTTP versions out there are 1.0 and 1.1 although version 0.9 is still used in places.  A common attempt to fool an application is by passing an invalid HTTP Version causing the server to not interpret the request correctly.  The "HTTP version" iRules command contains the request version and you can ensure that only valid requests are processed and allowed to your app servers with this iRule:

when RULE_INIT {
  set INFO 0
  set DEBUG 0
  #------------------------------------------------------------------------
  # HTTP Version
  #------------------------------------------------------------------------
  set sec_http_version_enabled 1
  set sec_http_version_block 1
  set sec_http_version_alert 1
  set sec_http_versions [list \
  "0.9" \
  "1.0" \
  "1.1" \
  ]
}
when HTTP_REQUEST {
  #============================================================================
  # HTTP Version
  #============================================================================
  if { $::INFO } { log local0. "ASSERTION: http_version" }
  if { $::sec_http_version_enabled } {
    if { $::DEBUG } { log local0. "  HTTP Version: [HTTP::version]" }
    if { ! [matchclass [HTTP::version] equals $::sec_http_versions ] } {
      if { $::sec_http_version_alert } { log local0. "  SEC-ALERT: Invalid HTTP Version found: '[HTTP::version]'" }
      if { $::sec_http_version_block } { reject }
    } else {
      if { $::DEBUG } { log local0. "  PASSED" }
    }
  }
}

 

In the RULE_INIT method I've created a few global variables enabling one to turn on or off the verification.  Without all the extra conditionals, the iRule can be stripped down to the following couple of lines:

when RULE_INIT {
  set sec_http_versions [list "0.9" "1.0" "1.1" ]
}
when HTTP_REQUEST {
  if { ! [matchclass [HTTP::version] equals $::sec_http_versions ] } {
    reject
  }
}

 

Get the Flash Player to see this player.
Published Aug 13, 2007
Version 1.0

Was this article helpful?

4 Comments

  • Puli's avatar
    Puli
    Icon for Nimbostratus rankNimbostratus
    Joe,

     

     

    since its being 3 years since this article is published, is there a newer update of these security guidelines ?

     

     

    Just checking if there's another location.

     

    thanks.

     

    Puli
  • We've had issues applying this on v11 systems.

     

     

    01070151:3: Rule [/Common/Lab6aa] error: Unable to find value_list (http) referenced at line 5: [matchclass [HTTP::version] equals $::http]

     

     

    with this iRule

     

     

    when RULE_INIT {

     

    set value [list "0.9" "1.0" "1.1" ]

     

    }

     

    when HTTP_REQUEST {

     

    if { ! [matchclass [HTTP::version] equals $::value ] } {

     

    reject

     

    }

     

    }
  • This doesn't seem to work any more as HTTP::version will only ever return 0.9, 1.0 or 1.1.

     

     

    If I use fiddler to send HTTP version 2.0, HTTP::version returns 1.0 while 1.9 returns 0.9.

     

     

    Only way we can find to do this is grabbing the TCP data and pulling the original HTTP version out of that data.
  • Here's an update for v11. when RULE_INIT { set sec_http_versions [list "0.9" "1.0" "1.1" ] } when HTTP_REQUEST { if { ! [matchclass [HTTP::version] equals $::sec_http_versions ] } { reject } }