Forum Discussion

Chenco_322726's avatar
Chenco_322726
Icon for Nimbostratus rankNimbostratus
Jan 24, 2018

Irule to block Requests with specific word

Hello All, I've many websites hosted behind F5 Lately im getting alot of spam through the "contact-us" form with a specific words like " viagra " or something like that. Is there any possible way to block POST requests with the word "viagra" ?

 

Thanks in Advance.

 

3 Replies

  • This isn't tested, but may be a useful starting point for you. You can use HTTP::collect to collect payload data and find what you're looking for in HTTP_REQUEST_DATA.

    Putting restricted words in a datagroup means you don't have to change the iRule everytime you add a new word.

     DATAGROUP
    ltm data-group internal restricted_dg {
        records {
            restricted_word {}
        }
        type string
    }
    
    IRULE
    when HTTP_REQUEST {
        if {[HTTP::method] eq "POST"} {
            HTTP::collect 100    
        }
    }
    
    when HTTP_REQUEST_DATA {
        set payload [HTTP::payload]
        if {[class match $payload contains "restricted_dg"]} {
            log local0. "Rejecting restricted content" 
            reject
        }
    }
    

    HTTP::payload https://devcentral.f5.com/wiki/iRules.HTTP__payload.ashx

    HTTP::collect https://devcentral.f5.com/wiki/iRules.HTTP__collect.ashx

  • Updated post with fully working iRule using datagroup

    Datagroup:

    ltm data-group internal restricted_dg {
        records {
            restricted {}
        }
        type string
    }
    

    Testing

    curl --data "param1=restricted&param2=notrestricted" http://10.1.1.1

    Jan 24 14:13:20 BIGIP info tmm1[19064]: Rule /Common/ls-http-collect : Rejecting restricted content

    iRule:

    when HTTP_REQUEST {
        if {[HTTP::header exists "Content-Length"] && [HTTP::header "Content-Length"] <= 1048576} {
            set content_length [HTTP::header value "Content-Length"]
        } else {
            set content_length 1048576
        }
    
        if { $content_length > 0} {
            if {[HTTP::method] eq "POST"} {
                HTTP::collect [HTTP::header "Content-Length"]
            }
        } else {
            log local0. "ERROR! Content Length = $content_length"
        }
    }
    
    when HTTP_REQUEST_DATA {
        set payload [HTTP::payload]
        if {[class match $payload contains "restricted_dg"]} {
            log local0. "Rejecting restricted content" 
            reject
        }
    }
    
  • Try this code to prevent issue. the problem may be the variable payload contains space and the code fails as the following string in the payload is read as a new argument. this solution will bypass the issue but may let some SPAM get in.

     

     Collect a request payload
    when HTTP_REQUEST {
    
      if {[HTTP::method] eq "POST"}{
         Trigger collection for up to 1MB of data
        if {[HTTP::header "Content-Length"] ne "" && [HTTP::header "Content-Length"] <= 1048576}{
          set content_length [HTTP::header "Content-Length"]
        } else {
            set content_length 1048576
        }
         Check if $content_length is not set to 0
        if { $content_length > 0} {
          HTTP::collect $content_length
        }
      }
    }
    
    when HTTP_REQUEST_DATA {
        set payload [HTTP::payload]
        catch {
            if {[class match $payload contains "restricted_dg"]} {
                log local0. "Rejecting restricted content" 
                reject
            }
        }
        HTTP::release
    }