For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

NZ_David_20489's avatar
NZ_David_20489
Icon for Nimbostratus rankNimbostratus
Oct 09, 2013

How to match multiple HTTP headers

I've been tasked with creating an iRule that searches for a header of 'screen' and field of 'ABC'. The iRule (or part of iRule) is below:

 } elseif {[string tolower [HTTP::header value screen]] equals "ABC" and ${cert-check} != 1 } {
 HTTP::respond 403

(pls ignore the Cert check) The header check seems to be working as expected when 1 header is included, as per below. (Successful test provides a 403, failed test provides a 404).

 [root:Active] config  curl -I https://1.1.1.1/ -H "screen: ABC" -k
 HTTP/1.0 403 Forbidden
 Server: BigIP
 Connection: Keep-Alive
 Content-Length: 0

  [root:Active] config  curl -I https://1.1.1.1/ -H "screen: abc" -k
  HTTP/1.0 403 Forbidden
  Server: BigIP
  Connection: Keep-Alive
  Content-Length: 0

However when I add two Headers I get (the latter 404 means its not being picked up by the iRule):

  [root:Active] config  curl -I https://1.1.1.1/ -H "screen: logon" -H "screen: abc" -k
  HTTP/1.0 403 Forbidden
  Server: BigIP
  Connection: Keep-Alive
  Content-Length: 0

  [root:Active] config  curl -I https://1.1.1.1/ -H "screen: abc" -H "screen: logon" -k
  HTTP/1.1 404 Not Found
  Connection: close
  Date: Tue, 08 Oct 2013 23:55:18 GMT
  Content-Length: 1214
  Content-Type: text/html
  X-Powered-By: Servlet/2.4 JSP/2.0

Can anyone identify whats incorrect or needs to be amended on the iRule to resolve this?

5 Replies

  • sorry iRule should show a lower case abc: } elseif {[string tolower [HTTP::header value screen]] equals "abc" and ${cert-check} != 1 } { HTTP::respond 403
  • It's a little odd because this appears to actually work with multiple headers in 11.3:

    when HTTP_REQUEST {
        if { [string tolower [HTTP::header screen]] equals "abc" } {
            log local0. "match"
        }
    }
    

    What version are you on?

    In lieu of the above, you could also iterate through the list of headers like this:

    when HTTP_REQUEST {
        foreach x [HTTP::header names] {
            if { ( $x equals "screen" ) and ( [string tolower [HTTP::header $x]] equals "abc" ) } {
                log local0. "match"
                break
            }
        }
    }
    
  • Just to test, try switching the abc value to the second header and screen to the first. This should prove it's only reading the last header.