For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

DFeike_160744's avatar
DFeike_160744
Icon for Nimbostratus rankNimbostratus
Jul 09, 2015

iRule to check for strings in xml

Hi guys,

i am currently struggling to build the correct syntax to do the following. I have http requests which contain a good amount of XML. Here is an extract from a pcap.

---snip

POST /TestServer/ HTTP/1.1

Content-Type: application/soap+xml; charset=utf-8

Host: win-2008-srv:2125

Content-Length: 1804

Expect: 100-continue

Connection: Keep-Alive

HTTP/1.1 100 Continue

http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">http://tempuri.org/IClientServices/HeartbeatExurn:uuid:506e2cc1-62d0-4c27-97f9-ea252f40bb86http://www.w3.org/2005/08/addressing/anonymoushttp://schemas.datacontract.org/2004/07/.Common.Interfaces.Heartbeat" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">http://schemas.datacontract.org/2004/07/.Common.Interfaces">Demo3.2.2.3643WORKGROUPS-1-5-32-544; S-1-1-0; S-1-5-11true2015-08-12T00:00:00TEST-CLIENT

---snip end

I've found that "a:MessageID" and "c:MachineName" are in every request and i want these be the criteria to grant access to a server.

So far my idea was something like this:

when HTTP::request {
    if { [string exists "MessageID" and "machineName"] {
        pool default
    } else {
        drop
    }
}
}

but of course i can't even save it via iRule editor because of parsing errors and i am really an iRule newbie 😉

Any help is appreciated.

Best regards

David

2 Replies

  • Well technically you're code might look something like this:

     

    when HTTP_REQUEST {    
        if { [HTTP::header exists Content-length] }        
            HTTP::collect [HTTP::header Content-Length]
        } else {        
            drop
        }
    }    
    when HTTP_REQUEST_DATA {    
        if { ( [HTTP::payload] contains "MessageID" ) and ( [HTTP::payload] contains "MachineName" ) } {        
             good request
        } else {        
            drop
        }
    }

    The above should very specifically limit access to only requests that have a Content-Length header and contain these two values in the payload. But...

     

    The example request you give is part of a 100-continue, which usually implies another request is coming with the rest of the payload. Are you certain, from captures, that every request has these two values? Will these values be in the very first requests?

     

  • Hi Kevin,

     

    thanks for the code. I will try this once the application owner has time to implement some changes with me.

     

    I am indeed quite sure that in each request a Content-Length Header and these two values are in the payload. The sample is from the first packet after the tcp handshake and is also the first packet with any payload. I suspect that this is just a application specific behaviour.

     

    best regards David