Forum Discussion

Joel_41531's avatar
Joel_41531
Icon for Nimbostratus rankNimbostratus
May 27, 2009

Blocking insecure log-in page

We terminate https on the F5, and pass traffic to the web apps on port 80. Consequently, I have an interesting problem. I have a log-in page (/store/user/login.jhtml) that should only be accessed via https. On the ASM, both http and https flow through the same policy (I can't identify which is secure/non-secure), so a custom attack sig using the URI would fail (block both secure and non-secure, when I only need the non-secure blocked).

 

 

There is no way to navigate to the insecure log-in page, but a pen-tester found it, so now I've got to fix it. Apps has a problem fixing it (same reason I do -- they can't identify secure/non-secure), and we'd like to stay away from an iRule (CPU expensive).

 

 

I've defined the specific page as an object (we're on 9.4.5), but I don't know how to block that specific object.

 

 

Is there any way to write an attack sig that blocks a specific object? Or am I missing something basic?

 

 

Thanks!

 

 

Joel
  • Benjamin_9036's avatar
    Benjamin_9036
    Historic F5 Account
    Hey Joel,

     

     

    The ASM should be aware of HTTP versus HTTPs objects depending upon which port the request arrives on. With this you could use a few possible solutions.

     

     

    a) Create a parameter for the HTTP object (perhaps even flow parameters with 'Mandatory Parameter' checked. This could be a static parameter with an obscure (totally random?) single value in the static list and would mean that unless someone knew the (hopefully) obscure/random parameter name *and* value that they would be blocked when accessing this page. This would probably get you by the auditor evaluation, but there is a possibility, no matter how remote, that somebody would either know, guess, or fuzz the parameter name and value and access the page. The cleaner solution is (probably):

     

     

    b) Assuming that you use two different virtual servers for this traffic (a port 80 and a port 443) you could create an HTTP Class for the port 80 virtual server that matched this URI and then redirected the traffic to its HTTPS equivalent, while the normal class with a more broad match remains to process all other traffic.

     

     

    c) I suppose, though I haven't tested this, that depending on what your current HTTP objects look like, you could create a wildcard HTTP object that would also match this page. Either '*' or even "/store/user/*" and then apply an attack signature that would block on uricontent of "/store/user/login.jhtml". Since you (presumably) have this object specifically defined as an HTTPS object, the object would take precedence over the signature and *should* only trigger for the HTTP objects that it matches.

     

     

    I could _probably_ keep going, but one of these should get things going for you. Let me know how it goes! =]

     

     

    // Ben
  • Ben,

     

     

    Appreciate the answers, but neither of the 2 I tried (a and c) worked for me. Option b is a bit more difficult -- ASM is on 3 stand-alone 8800's, configured in a pool, in which the Load-Balancing LTM 8800's send traffic. All of this traffic is from one http class per site -- I can hit the Load-Balance team up to do what you're suggesting, but I'd rather do it on the ASM's.

     

     

    I created the parameter as a static -- and checked all the Access, Length and Input Violations on the blocking settings. It never alarmed, and subsequently, was never blocked. I didn't try it as a flow parameter, but that will be next. I've never done a Flow-based object parameter, and need to research it a little further.

     

     

    Option c just didn't work -- and after I applied the signature globally, it wasn't blocking on any site's login URL, so I may have done something wrong. My signature was simple: uricontent:"/store/user/login.jhtml"; I also tried "headercontent", which didn't work either. I had turned off staging, and I was checking for violations in the log -- nothing.

     

     

    Any further ideas? I'm still pretty stumped.

     

     

    Thanks for your help!

     

     

    Joel
  • Benjamin_9036's avatar
    Benjamin_9036
    Historic F5 Account
    Hey Joel,

     

     

    If I understand your set up now, none of those would really work. If the traffic for both HTTPs and HTTP arrives at the same port 80 VS on the ASM, there is little way to tell them apart. Truly any trace of which protocol it arrived on will be absent by the time it arrives there, then.

     

     

    I think you will have to engage the LTM in front to be able to distinguish between them, but understanding the set up better now, there are some more graceful solutions. The LTM could perform header insertion on the individual VIPs, i.e. the port 443 VIP could insert "X-HTTPS-PROTO: Huzzah!" and the port 80, "X-HTTP-PROTO: Wheee!". Then your ASM could use HTTP Classes to look for these and sort out the traffic as above.

     

     

    It may be slightly more invasive, but you could also configure two VSs on your ASM and configure the LTMs to send to them differently on the ASM, so the traffic arrived at the ASM as it would were it getting it direct form the client.

     

     

    The trouble is that with only the HTTP headers there is nothing to really denote whether HTTPS or HTTP was used in most cases. Try watching a few clicks around with Live HTTP Headers, HTTP Watch, or even Paros/Scarab/Burp sometime and try to spot anything in these that denotes whether the connection was sent HTTP or HTTPs. (Note that some of these might show the full address in the request string: GET http://abc.com, but this is not what is actually sent) Even taking a tcpdump on the ASM and trying to sort out the difference between the requests that *were* HTTP and HTTPS would help indicate the difficulty. =]

     

     

    The header insertion on the LTM seems like the least invasive and cleanest solution I can think of now. I will ponder it over the weekend, however, to see if anything else leaps out at me. Cheers for now!

     

     

    // Ben
  • Just to close this out, here's what I did. We have an iRule that injects a header tag to let the backend systems know if the connection is secure/insecure. It's really simple -- if arrived on port 80, is_secure=0, if arrived on port 443, is_secure=1. I utilized this, in a headercontent statement, in conjunction with the uri, and it worked.

     

     

    Joel
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    Hi Tacobell,

    You can insert a custom HTTP header on the HTTPS VS with a custom HTTP profile that has the header to remove set to X-HTTPS and the header to insert set to 'X-HTTPS: 1'. On the HTTP VS, you could do the same with the header to insert's value set to 0.

    
     HTTP profile for the HTTP virtual server
    profile http http_profile_https_0 {
       defaults from http
       header insert "X-HTTPS: 0"
       header erase "X-HTTPS"
    }
     HTTP profile for the HTTPS virtual server
    profile http http_profile_https_1 {
       defaults from http
       header insert "X-HTTPS: 1"
       header erase "X-HTTPS"
    }
    

    Aaron