Forum Discussion

Bubbagump_12531's avatar
Bubbagump_12531
Icon for Nimbostratus rankNimbostratus
Oct 30, 2013

Prevent X-Forwarded-For spoofing

We insert an X-Forwarded-For header to pass back to our web servers. One application we have looks to this header to allow or deny certain servers access to us. However, we want to prevent spoofing the header for obvious reasons. The hope is that the LTM can peel off any outside X-Fordwarded-For headers and replace them with its own X-Fordwarded-For that has the IP of the actual client that is connecting. We are running 11.4.1 which has an "Accept XFF" option, but this is disabled. Reading the docs makes it sound like having that option disabled will give us what we need, but it does not work. I also tried adding X-Forwarded-For to the "Request Header Erase" option and it removes all X-Forwarded-For headers even the ones the LTM creates.

 

I can spoof X-Fordwarded-Fors no sweat still. Any bright ideas on how to peel off outside X-Forwarded-Fors?

 

23 Replies

  • I got that, I just don't know how to add the header to the rule. I tried

    when HTTP_REQUEST {
    foreach x [HTTP::header names] {
        if { [string tolower $x] equals "x-forwarded-for" } {
            HTTP::header remove $x
            HTTP::header replace X-FORWARDED-FOR [IP::client_addr]
        }
        else
          { HTTP::header insert X-FORWARDED-FOR [IP::client_addr]}
    }   
    

    }

    But that tacked on seemingly a zillion headers

  • Try this:

    when HTTP_REQUEST {
        set xff 0
        foreach x [HTTP::header names] {
            if { [string tolower $x] equals "x-forwarded-for" } {
                set xff 1
                HTTP::header remove $x
                HTTP::header insert X-FORWARDED-FOR [IP::client_addr]
            }
        }   
        if { $xff == 0 } {
            HTTP::header insert X-FORWARDED-FOR [IP::client_addr]
        }
    }
    
    • uni's avatar
      uni
      Icon for Altostratus rankAltostratus
      An interesting issue. RFC 2616 section 4.2 says that header names are case insensitive, in which case I think the BigIP HTTP::header replace and remove should be case insensitive too.
    • eey0re_68979's avatar
      eey0re_68979
      Icon for Altocumulus rankAltocumulus
      Tested in 11.6.0, [HTTP::header remove "X-Forwarded-For"] is case insensitive and removes all case permutations of the header, avoiding the need for a foreach loop. The original answer above is now sufficient.
  • As far as I know, there's no harm in trying to remove missing headers so this rule can be pretty simple. This is a well-tested rule and should be used without any HTTP profile XFF options:

    when HTTP_REQUEST {
      HTTP::header remove X-Forwarded-For    
      HTTP::header insert X-Forwarded-For [IP::remote_addr]
    }
    
  • So if you want to deny XFF spoofing attack and see the client IP address at the same time, you have to disable XFF option on HTTP profile and then apply following irule will be enough ?

     

    when HTTP_REQUEST { foreach x [HTTP::header names] { if { $x equals "X-FORWARDED-FOR" } { HTTP::header remove X-FORWARDED-FOR HTTP::header replace X-FORWARDED-FOR [IP::client_addr] } }

     

    }

     

  • So if you want to deny XFF spoofing attack and see the client IP address at the same time, you have to disable XFF option on HTTP profile and then apply following irule will be enough ?

    when HTTP_REQUEST {

    foreach x [HTTP::header names] {
        if { $x equals "X-FORWARDED-FOR" } {
            HTTP::header remove X-FORWARDED-FOR
            HTTP::header replace X-FORWARDED-FOR [IP::client_addr]
        }
    }   
    

    }