Host Header Validation
Greetings,
I have been tasked with crafting an iRule to validate the host header of incoming packets to a given virtual server. I have tried a few different irules to attempt this an yet I am told that the security team is able to modify the host header of the packet and still get around the iRule's checks. Would someone be able to look over the iRule's and tell me what I may be missing/doing wrong?
when HTTP_REQUEST if { [HTTP::host] equals "xyz.com"}{ pool /Common/xyz_pool }else{ reject } }
(this one below is more an attempt to force the correct one than validate whats coming in)
when HTTP_REQUEST { if {[HTTP::header exists Host]}{ HTTP::Header replace Host xyz.com }else{ HTTP::header replace Host xyz.com } }
A data-group is a convenience rather than a necessity.
I tried the following on 11.5.4:
when HTTP_REQUEST { if { [HTTP::host] ne "xyz.com" } { reject } }
I tried all of the following combinations:
- HTTP/1.1 Host header xyz.com;
- HTTP/1.1 Host header foo.com;
- HTTP/1.0 no Host header;
- HTTP/1.1 Host header xyz.com followed by HTTP/1.0 no Host header;
- HTTP/1.1 Host header xyz.com followed by HTTP/1.1 Host header foo.com
Case 1: allowed;
Case 2: rejected (i.e., TCP RST);
Case 3: rejected;
Case 4: allowed then rejected;
Case 5: allowed then rejected.
Incidentally, if a pool is assigned to the VS, then the else clause isn't needed (it's the default anyway).
Having said all of that, your issue may be relate to this note, found in the reject explanation:
Subsequent code in the current event in the current iRule or other iRules on the VS are still executed prior to the reset being sent.
I recommend putting a return after the reject.