Forum Discussion

Greg_33558's avatar
Greg_33558
Icon for Nimbostratus rankNimbostratus
Mar 30, 2015

Can I have URLs not on Allowed List trigger a 404 instead of a 200?

How can I 404 anything that's not on the Approved URL list instead of returning the Default Response page which is an HTTP 200?

 

I have a small web application which is encompassed by about a dozen Allowed URL entries. For violations on these URLs, of course, I want the standard Default Response to go out at an HTTP 200 with useful text:

 

Your support ID is: <%TS.request.ID()%>

For any other URL that hits the system - and I'm sure they'll be a lot of them when someone scans it - I don't care to give away information by sending what is clearly F5 ASM support ID, and I don't care to encourage the scanning tool with an HTTP 200 response when a 404 is appropriate.

 

I had been thinking I could just check the ASM violation in an ASM_REQUEST_BLOCKING event and modify the response, similarly to the way that ASM::payload allows me to adjust the text that the ASM is sending. But I don't see any method for changing the HTTP response code; even HTTP::response is read-only.

 

Is there a supported way to issue a different response page for VIOLATION_OBJ_DOESNT_EXIST? Alternately, is there a way to adjust in with an iRule?

 

Any help appreciated.

 

3 Replies

  • Excellent, that got me there, but with some caveats:

    I needed to use the HTTP_RESPONSE_RELEASE event instead of HTTP_RESPONSE / HTTP_RESPONSE_DATA, because those are not triggered when the ASM decides to block a request - to quote iRules Event Order, "These events are triggered after the request has been sent to the server, the server has processed the request and the LTM receives a response from the server." If the ASM blocks the request, it's never sent to the server.

    Fortunately I ran across SOL14211, "Using an iRule to parse post-ASM requests and responses (11.x)", which addressed this exact issue.

    In the end, this is working for me:

    when HTTP_REQUEST { 
        set asm_404_not_found 0
    }
    
    when ASM_REQUEST_BLOCKING { 
        set asm_info [ASM::violation_data]
         Any response tweaking should only be done in blocking mode!!!
        if {[string compare [ASM::status] "blocked"] == 0} {
            if {[string first {VIOLATION_OBJ_DOESNT_EXIST} [lindex $asm_info 0]] != -1} {
                set asm_404_not_found 1
            }
        }
    }
    
    when HTTP_RESPONSE_RELEASE {
        if {$asm_404_not_found == 1} {
            HTTP::respond 404 content "Not Found"
        }
    }
    

    Now, as a caveat, I notice that according to HTTP_RESPONSE_RELEASE documentation, the HTTP::respond command is "disabled" in the HTTP_RESPONSE_RELEASE event... but that's not the behavior I'm seeing under 11.6.

    Thanks for the answer!