Forum Discussion
Extra pair/s of eyes need to verify HTTP::cookie logic
Can anyone see glaring logic issues with the following?
when HTTP_REQUEST { set LogString "Client [IP::client_addr]:[TCP::client_port] -> [HTTP::host][HTTP::uri]" log local0. "=============================================" log local0. "$LogString (request)" foreach aHeader [HTTP::header names] { Print the header info log local0. "$aHeader: [HTTP::header value $aHeader]" } foreach aCookie [HTTP::cookie names] { Log the cookie name and value log local0. "Cookie Name: $aCookie, Cookie value: [HTTP::cookie value $aCookie]" } if { ([HTTP::header value "User-Agent"] contains "Mozilla") || ([HTTP::header value "User-Agent"] contains "Opera") || ([HTTP::header value "User-Agent"] contains "curl") && ([string tolower [HTTP::uri]] matches_regex {restservicesintstest}) && (not [HTTP::cookie names] contains ".fb") } then { reject log local0. "Client browser connection to REST Host:[HTTP::host]; URI=[HTTP::uri]. No SSO Cookie Detected in Header, Client IP:[IP::client_addr] has been blocked" log local0. "=============================================" } else { log local0. "Client browser connection to REST Host:[HTTP::host]; URI=[HTTP::uri] for Client IP:[IP::client_addr] allowed!" log local0. "=============================================" } }
Particularly this piece:
if {
([HTTP::header value "User-Agent"] contains "Mozilla")
|| ([HTTP::header value "User-Agent"] contains "Opera")
|| ([HTTP::header value "User-Agent"] contains "curl")
&& ([string tolower [HTTP::uri]] matches_regex {restservicesintstest})
&& (not [HTTP::cookie names] contains ".fb")
We're logging cookies:
Feb 24 15:57:23 lb01 info tmm[15541]: Rule /Common/SecAuthREST-IntS-Test--DEBUG2 : Client 10.0.22.218:59677 -> restservicesintstestv7.fb/test/alertsrestserviceintA/rest/alert/isAlive (request) Feb 24 15:57:23 lb01 info tmm[15541]: Rule /Common/SecAuthREST-IntS-Test--DEBUG2 : Host: restservicesintstestv7.fb Feb 24 15:57:23 lb01 info tmm[15541]: Rule /Common/SecAuthREST-IntS-Test--DEBUG2 : User-Agent: curl/7.47.0 Feb 24 15:57:23 lb01 info tmm[15541]: Rule /Common/SecAuthREST-IntS-Test--DEBUG2 : Accept: / Feb 24 15:57:23 lb01 info tmm[15541]: Rule /Common/SecAuthREST-IntS-Test--DEBUG2 : Cookie: test2.fb=foobar Feb 24 15:57:23 lb01 info tmm[15541]: Rule /Common/SecAuthREST-IntS-Test--DEBUG2 : Cookie Name: test2.fb, Cookie value: foobar Feb 24 15:57:23 lb01 info tmm[15541]: Rule /Common/SecAuthREST-IntS-Test--DEBUG2 : Client browser connection to REST Host:restservicesintstestv7.fb; URI=/test/alertsrestserviceintA/rest/alert/isAlive for Client IP:10.0.22.218 allowed!
However when we don't provided the test2.fb cookie, not [HTTP::cookie names] contains ".fb" isn't triggering in order to reject the connection:
Feb 24 15:57:18 lb01 info tmm[15541]: Rule /Common/SecAuthREST-IntS-Test--DEBUG2 : Client 10.0.22.218:59675 -> restservicesintstestv7.fb/test/alertsrestserviceintA/rest/alert/isAlive (request) Feb 24 15:57:18 lb01 info tmm[15541]: Rule /Common/SecAuthREST-IntS-Test--DEBUG2 : Host: restservicesintstestv7.fb Feb 24 15:57:18 lb01 info tmm[15541]: Rule /Common/SecAuthREST-IntS-Test--DEBUG2 : User-Agent: curl/7.47.0 Feb 24 15:57:18 lb01 info tmm[15541]: Rule /Common/SecAuthREST-IntS-Test--DEBUG2 : Accept: / Feb 24 15:57:18 lb01 info tmm[15541]: Rule /Common/SecAuthREST-IntS-Test--DEBUG2 : Client browser connection to REST Host:restservicesintstestv7.fb; URI=/test/alertsrestserviceintA/rest/alert/isAlive for Client IP:10.0.22.218 allowed!
I'm thinking that the HTTP::cookie statement isn't quite right, or that there must be a better way to string all of those conditions together.
Any insight or suggestions would be appreciated. Thanks, Eric
3 Replies
- Mark_22062
Nimbostratus
Hi Eric, Any chance you could log the User-Agent as well? Why not check if HTTP::cookie exists? Hi Eric,
I can only repeat the answer I gave you in your last post...
https://devcentral.f5.com/questions?pid=44725answer132972
when HTTP_REQUEST { set LogString "Client [IP::client_addr]:[TCP::client_port] -> [HTTP::host][HTTP::uri]" log local0. "=============================================" log local0. "$LogString (request)" foreach aHeader [HTTP::header names] { Print the header info log local0. "$aHeader: [HTTP::header value $aHeader]" } foreach aCookie [HTTP::cookie names] { Log the cookie name and value log local0. "Cookie Name: $aCookie, Cookie value: [HTTP::cookie value $aCookie]" } if { (( [HTTP::header value "User-Agent"] contains "Mozilla" ) or ( [HTTP::header value "User-Agent"] contains "Opera" ) or ( [HTTP::header value "User-Agent"] contains "curl" )) and ( [string tolower [HTTP::uri]] matches_regex {restservicestest} ) and not ( [HTTP::cookie names] contains ".fb" ) } then { reject log local0. "Client browser connection to REST Host:[HTTP::host]; URI=[HTTP::uri]. No SSO Cookie Detected in Header, Client IP:[IP::client_addr] has been blocked" log local0. "=============================================" } else { log local0. "Client browser connection to REST Host:[HTTP::host]; URI=[HTTP::uri] for Client IP:[IP::client_addr] allowed!" log local0. "=============================================" } }... to show you that this syntax is working you may try this test snipped...
set user_agent "Blah Mozilla Blah" set http_uri "/folder/restservicestest/folder/file.txt" set cookie_names "cookie1 cookie.fb cookie2" set LogString "Client [IP::client_addr]:[TCP::client_port] -> [HTTP::host][HTTP::uri]" log local0. "=============================================" log local0. "$LogString (request)" if { (( $user_agent contains "Mozilla" ) or ( $user_agent contains "Opera" ) or ( $user_agent contains "curl" )) and ( [string tolower $http_uri] matches_regex {restservicestest} ) and not ( $cookie_names contains ".fb" ) } then { reject log local0. "Client browser connection to REST Host:[HTTP::host]; URI=[HTTP::uri]. No SSO Cookie Detected in Header, Client IP:[IP::client_addr] has been blocked" log local0. "=============================================" } else { log local0. "Client browser connection to REST Host:[HTTP::host]; URI=[HTTP::uri] for Client IP:[IP::client_addr] allowed!" log local0. "=============================================" }As already Noted: The iRule implements is a typical Blacklist. So it wouldn't block unknown "User-Agents" and/or unknown URIs. If this is not desired for you, then change the iRule to become a Whitelist where you allow just certain User-Agents, certain URIs and then enforce the Cookie to be present. And then block everything else which is not explicitly whitelisted...
White-List approach
when HTTP_REQUEST { set LogString "Client [IP::client_addr]:[TCP::client_port] -> [HTTP::host][HTTP::uri]" log local0. "=============================================" log local0. "$LogString (request)" foreach aHeader [HTTP::header names] { Print the header info log local0. "$aHeader: [HTTP::header value $aHeader]" } foreach aCookie [HTTP::cookie names] { Log the cookie name and value log local0. "Cookie Name: $aCookie, Cookie value: [HTTP::cookie value $aCookie]" } if { (( [HTTP::header value "User-Agent"] contains "Mozilla" ) or ( [HTTP::header value "User-Agent"] contains "Opera" ) or ( [HTTP::header value "User-Agent"] contains "curl" )) and ( [string tolower [HTTP::uri]] matches_regex {restservicestest} ) and ( [HTTP::cookie names] contains ".fb" ) } then { log local0. "Client browser connection to REST Host:[HTTP::host]; URI=[HTTP::uri] for Client IP:[IP::client_addr] allowed!" log local0. "=============================================" } else { reject log local0. "Client IP:[IP::client_addr], User-Agent:[HTTP::header value "User-Agent"] and Cookies:[HTTP::cookie names] connection to REST Host:[HTTP::host]; URI=[HTTP::uri] has been blocked" log local0. "=============================================" } }Cheers, Kai
- Eric_Weiss_2486
Nimbostratus
I figured it out and was able to come up with something a little more elegant. Also, added logging for cookie and user-agent. The rule broke when adding all of the || and && conditions, like above. Changed logic for HTTP::cookie so that it isn't using 'not' (since that expects a numeric value instead of alpha), and changed the HTTP::uri regex that wasn't working, to HTTP::host.
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
