ASM cookie, modifying "domain" field
Is it possible to modify "domain" field in the ASM cookie ? As it appears ASM is using a hostname from http header, unfortunately the host is replaced to an internal hostname (required by an app) in an irule. So scanners point that this is a vulnerability.436Views0likes2CommentsChange default cookie insert name
Is there any possibility to change the default cookie name (BIGipServer) for a cookie insert persistence profile? We want to use a standard cookie insert profile across several virtual servers, but avoiding the name "BIGipServer". But we still need the "" as a dynamic variable. Is there some variable syntax available for the cookie name field or can we modify the default "BIGipServer" string? Or is this somewhere hardcoded in the OS? Thank you! Regards Stefan 🙂592Views1like5CommentsAPM (& LTM) Session & Cookie Information - Chrome Extension
Problem this snippet solves: If you've ever troubleshooted APM Portal Access issues, you know how annoying it can be to find the decoded internal url. Note: This extension has been updated as more of an APM and LTM extension as opposed to just an APM one. This chrome extension seeks to make that quick and easy by showing the decoded information. It will also display the cookies for that site (including the ever-useful MRHSession and LastMRH_Session cookies) and allows you to delete cookies directly from the extension (useful for testing session timeout if you delete the MRHSession cookie). Version History 1.1 - Initial version Includes APM portal access decoded url information 1.2 - 2016.04.01 Added list of cookies associated with the current site (shows cookie name, domain and value) 1.3 - 2016.04.25 Added ability to delete cookies from the extension for the site (Known Issue: if you have multiple cookies with the same name that match the page, deleting one will delete all of them) Added decoded BIG-IP persistence cookie value in parenthesis to the list for quicker reference 1.4 - 2016.06.30 Rebuilt the popup page using AngularJS Introduced (but still disabled) options page and client-side functionality (will need iRules development as well) 1.5 - 2016.09.07 Enabled the options page again, and finished code to allow the extension to add a header to requests on specific domains (user specified) 1.5.1 - 2016.09.18 Updated the icon, and removed APM and replaced with debugging icon since this has morphed to APM and LTM usefulness 1.6 - 2016.12.19 Now enables the extension when it determines a persistence cookie (based on value format) Added a link that will popup APM session details (when management url specified in options page) (Note: must be logged into the management GUI already or else it won't redirect properly). Used alongside my APM Tampermonkey script you can see the session variables as well as the session detail 1.7 - 2017.09.03 Added local tracking of sites that appear to use F5 BigIP How to use this snippet: As Chrome doesn't really like unpublished extensions, and it's not in the Chrome App Store (yet), you'll have to install the extension in Developer Mode. Instructions Navigate to chrome://extensions Ensure that the Developer mode checkbox is enabled Sub-Method 1: Load unpacked extension (preferred method) Download all the code from the Github repository Click the Load unpacked extension button and select the src folder Sub-Method 2: Load the crx file (may not always be current) Download the crx from the Github repository From the file system, click and drag the .crx file onto the extension page to install it Code : https://github.com/jangins101/F5-APM-Session-Information Tested this on version: 11.5750Views0likes0CommentsHow to generate the persistence cookie with an iRule
Problem this snippet solves: When you configure a cookie persistence profile to use the HTTP Cookie Insert or HTTP Cookie Rewrite method, the BIG-IP system inserts a cookie into the HTTP response. The cookie value contains the encoded IP address and port of the destination server. Exemple of a cookie value : 1677787402.36895.0000 (See SOL6917 for more information about this topic) Let's assume that you want your pool member to receive a copy of this cookie value in an HTTP header. Because for example you want your application to forge an url where the cookie value is in a GET parameter. (NOTE : I cannot modify the behavior of the application, I can only play with headers) Retrieving the cookie value is pretty easy with iRule : [HTTP::cookie value $cookie_name] But you'll notice that there is a little issue with this feature: when you are a new visitor, the persistence cookie is inserted in the HTTP response ... Meaning that for the very first hit made by the visitor, there will be NO cookie value to retrieve ... In my scenario it was an issue to miss this cookie value on the first hit, so I had to come up with a solution to forge the cookie value based on pool member IP and port when the persistence cookie is missing. I chose to adapt the code found here and there (thanks !) EDIT : Well I figured out that if you are not using a default route-domain the persistence cookie value will be different (see https://support.f5.com/csp/article/K6917 ) Here is the alternative code bloc to use IPv4 non-default route domains: set ADDR "[format %02x $a][format %02x $b][format %02x $c][format %02x $d]" set PORT [LB::server port] set COOKIE "rd2o00000000000000000000ffff${ADDR}o${PORT}" How to use this snippet: To summarize what the iRule does : if the persistence cookie doesn't exist (most likely because it's the very first hit), then calculate it from member IP and PORT (it obviously has to be after the "When LB_SELECTED" statement) ; else just read the existing cookie. You can set the $cookie_name parameter manually, or let the iRule identify it Code : when LB_SELECTED { #set cookie_name SERVERID # following function could determine persistence cookie name being used if not manually set by the previous line if {not [info exists cookie_name]} { if { [set cookie_name [PROFILE::persist mode cookie cookie_name]] eq "" } { set cookie_name "BIGipServer[getfield [LB::server pool] "/" 3]" } #Default cookie name requires the getfield "/" 3 purge otherwise it's /Common/pool_name } if { [set COOKIE [HTTP::cookie value $cookie_name]] == "" } { scan [LB::server addr] {%d.%d.%d.%d} a b c d set ADDR [expr { $a + $b * 256 + $c * 65536 + $d * 16777216 }] set PORT [ntohs [LB::server port]] set COOKIE "${ADDR}.${PORT}.0000" ## Following bloc must be used instead if you are using non-default route domains, see K6917 #set ADDR "[format %02x $a][format %02x $b][format %02x $c][format %02x $d]" #set PORT [LB::server port] #set COOKIE "rd2o00000000000000000000ffff${ADDR}o${PORT}" ######### unset a b c d ADDR PORT #log local0. "$cookie_name = $COOKIE created for [HTTP::uri]" } else { #log local0. "$cookie_name = $COOKIE already exists for [HTTP::uri]" } HTTP::header insert X-F5-persist $COOKIE } Tested this on version: 11.52.2KViews2likes1CommentSecure Cookie when the VIP is requested by IP (not URL)
Hello. I have a VIP config where the pool member is the one handling the cookie to the client. The pool member has a limitation when the client access the VIP via IP (not URL), the cookie is served not secured. I created this iRule which one of the side effects is an increased in the CPU utilization. when HTTP_RESPONSE { set cookies [HTTP::cookie names] foreach aCookie $cookies { HTTP::cookie secure $aCookie enable } } Is this the most efficient way? Is there a way to use a policy vs an irule? Thank you J349Views0likes2CommentsStop Those XSS Cookie Bandits iRule Style
In a recent post, CodingHorror blogged about a story of one of his friends attempts at writing his own HTML sanitizer for his website. I won't bother repeating the details but it all boils down to the fact that his friend noticed users were logged into his website as him and hacking away with admin access. How did this happen? It turned out to be a Cross Site Scripting attack (XSS) that found it's way around his HTML sanitizing routines. A user posted some content that included mangled JavaScript that made an external reference including all history and cookies of the current users session to an alternate machine. CodingHorror recommended adding the HttpOnly attribute to Set-Cookie response headers to help protect these cookies from being able to make their way out to remote machines. Per his blog post: HttpOnly restricts all access to document.cookie in IE7, Firefox 3, and Opera 9.5 (unsure about Safari) HttpOnly removes cookie information from the response headers in XMLHttpObject.getAllResponseHeaders() in IE7. It should do the same thing in Firefox, but it doesn't, because there's a bug. XMLHttpObjects may only be submitted to the domain they originated from, so there is no cross-domain posting of the cookies. Whenever I hear about modifications made to backend servers, alarms start going off in my head and I get to thinking about how this can be accomplished on the network transparently. Well, if you happen to have a BIG-IP, then it's quite easy. A simple iRule can be constructed that will check all the response cookies and if they do not already have the HttpOnly attribute, then add it. I went one step further and added a check for the "Secure" attribute and added that one in as well for good measure. when HTTP_RESPONSE { foreach cookie [HTTP::cookie names] { set value [HTTP::cookie value $cookie]; if { "" != $value } { set testvalue [string tolower $value] set valuelen [string length $value] #log local0. "Cookie found: $cookie = $value"; switch -glob $testvalue { "*;secure*" - "*; secure*" { } default { set value "$value; Secure"; } } switch -glob $testvalue { "*;httponly*" - "*; httponly*" { } default { set value "$value; HttpOnly"; } } if { [string length $value] > $valuelen} { #log local0. "Replacing cookie $cookie with $value" HTTP::cookie value $cookie "${value}" } } } } If you are only concerned with the Secure attribute, then you can always use the "HTTP::cookie secure" command but as far as I can tell it won't include the HttpOnly attribute. So, if you determine that HttpOnly cookies are the way you want to go, you could manually configure these on all of your applications on your backend servers. Or... you could configure it in one place on the network. I think I prefer the second option. -Joe383Views0likes0Commentsirule to remove all cookies
Hello, we are testing an irule to remove all cookie from the client browser after an idle time, the cookie for TCP isn't what we are looking for rather than the actual cookie sent to the server. any suggestion on how to achieve this, if I inserted a cookie manually I want the irule to delete it after I refresh the page. we are testing this on BIG-IP LTM ?irule example : when HTTP_REQUEST { } when HTTP_RESPONSE { set cookieNames [HTTP::cookie names] #array of cookies foreach aCookie $cookieNames { #adding the cookies to the array in a varaible aCookie HTTP::cookie remove $aCookie #removing the virable } }851Views0likes1CommentLooking for Feedback/Efficiency on Cookie Removal
Background: We have a homegrown portal that users log in to and then launch applications from. This portal injects a ridiculous number of cookies into the client. One or more of these cookies prevent an application from working correctly. My iRule that I quickly made to 'fix' the issue is below. Since I cannot modify the response to expire the cookies I don't want since that will break other applications if they attempt to launch them, I have to scrub any of the cookies I don't want to get to this application on every incoming request. Question(s): 1) Aside from fixing the portal (I want to replace it with APM...we'll see) is there another avenue I should be looking at to fix this besides an iRule? 2) Can my iRule be made more efficient through using switch or data groups? I couldn't figure out how to do that since I don't know of a way to do 'not equal' or not 'starts_with' within switch or how to get the data group syntax to work. There are more cookies I have to allow than included here. I shortened it. when HTTP_REQUEST { set cookies [HTTP::cookie names] log local0. "Inbound cookies are $cookies" foreach cookie $cookies { if { !($cookie starts_with "f5" or $cookie starts_with "" or $cookie starts_with "") }{ HTTP::cookie remove $cookie log local0. "Removing cookie $cookie" } } }318Views0likes2CommentsFixing Incomplete SAML SP Initiated Login
This is not really a question, because I already know the answer. I spent a fair amount of time and received awesome help from a few people on this forum. I wanted to post this here so others can avoid the same headache. Specific Issue: Service Provider sends what they call a "Partial SP Initiated Authentication." What really happens is that they perform a 302 Location redirect and have both SAMLRequest and RelayState parameters in the URL. However, SAMLRequest= is blank. They have neglected to deflate, 64-bit encode, and URL encode a SAML Request in their redirect. Fixing Missing SAML Request: Since the Service Provider is not sending a SAMLRequest, the F5 has to trigger an IdP initiated login, and this can be done with an iRule attached to the webtop Virtual Server. However, this will only get you connected to the landing page and does not take into account the RelayState parameter sent in the 302 Location redirect. Fixing the RelayState: The way this was accomplished was by creating back-to-back virtual servers, using cookies to pass the appropriate RelayState URI, and a Stream profile to modify the SAML Response on its way back to the user's web browser. Front-end Virtual Server: The front-end virtual server has 2 responsibilities. The first is to forward all traffic through from the user's web browser on to the webtop virtual server. This is a simple iRule. The second responsibility is to use a Stream profile to modify the SAML Response and append the missing RelayState information appropriately. Back-end Virtual Server: The back-end virtual server is for hosting the Access Policy and an iRule that catches the request, initiates an unsolicited IdP SAML Response, and passes the RelayState back to the front-end virtual server via a http cookie. Note: I took a shortcut on setting up the RelayState form element by pre-populating the SP connector with an "/" in the RelayState field. Front-end iRule to redirect all traffic to back-end virtual server: when HTTP_REQUEST { virtual /Common/VS_Portal log local0. "Forwarded to Portal" } Back-end iRule to initiate SAML Response and pass RelayState via cookie: when ACCESS_POLICY_COMPLETED { if { [string tolower [ACCESS::session data get session.server.landinguri]] contains "apps" } { if { [ACCESS::session data get session.server.landinguri] == "/saml/idp/profile/redirectorpost/sso" } { log local0. "SP initiated SAML detected, not sending redirect" } else { set relaystatevalue "[string map {"%2f" "/" "%3f" "?" "%3d" "="}[URI::query [ACCESS::session data get session.server.landinguri] "RelayState"]]" ACCESS::respond 302 Location "https://go.domain.com/saml/idp/res?id=/Common/SAML_APP" log local0. "IDP initiated SAML detected, sending redirect [URI::query [ACCESS::session data get session.server.landinguri] "RelayState"]" HTTP::cookie insert name "RelayState" value $relaystatevalue domain ".domain.com" return } } ` } **Front-end iRule to modify return traffic SAML Response and modify RelayState:** when HTTP_REQUEST { `set relaystatesetter 0 set relaystatevalue 0 set relaystateexists 0 if {[HTTP::cookie exists "RelayState"]}{ set relaystateexists 1 set relaystatevalue "[HTTP::cookie RelayState]" } log local0. "iRule Logger - HTTP_REQUEST Starting hostname=[HTTP::host];uri=[HTTP::uri]" if {[HTTP::uri] contains "RelayState"}{ log local0. "iRule Logger - HTTP_REQUEST RelayState Store Cookie hostname=[HTTP::host];uri=[HTTP::uri]" set relaystatesetter 1 set relaystatevalue "[string map {"%2f" "/" "%3f" "?" "%3d" "="}[URI::query [HTTP::uri] RelayState]]" log local0. "iRule Logger - RelayState is $relaystatevalue;relaystatesetter=$relaystatesetter" HTTP::cookie insert name "RelayState" value $relaystatevalue domain ".domain.com" } ` } when HTTP_RESPONSE { ` if {$relaystatesetter==1}{ HTTP::cookie insert name "RelayState" value $relaystatevalue domain ".domain.com" } log local0. "iRule Logger - HTTP_RESPONSE Triggered - relaystate=$relaystatevalue" if {$relaystateexists==1}{ log local0. "iRule Logger - HTTP_RESPONSE Triggered - relaystateexists=$relaystateexists" STREAM::expression "@@@" STREAM::enable } }716Views0likes1CommentSaml token convert to jwt
Hello, I create a iRule for convert saml token to JWT (json web token). It works well but I get a signatur error. I try many option and formats. But nothing works. I'm shure you can help me easily. I have creat a working access Profile with saml. Bigip is SP and an external IdP. Here my iRule. when ACCESS_ACL_ALLOWED { set hamacsha256 secret set secret_key "secret" get data from saml Session (APM->Manage Sessions-> Variables -> View) set user [ACCESS::session data get session.saml.last.nameIDValue] set sub [ACCESS::session data get session.saml.last.attr.name./EmployeeID] set nbf [ACCESS::session data get session.saml.last.validityNotBefore] set exp [ACCESS::session data get session.saml.last.validityNotOnOrAfter] set email [ACCESS::session data get session.saml.last.attr.name./identity/claims/emailaddress] set surname [ACCESS::session data get session.saml./Common/xyz_auth_ag.attr.name./identity/claims/surname] set givenname [ACCESS::session data get session.saml./Common/xyz_auth_ag.attr.name./identity/claims/givenname] set aud [ACCESS::session data get session.saml.last.assertionIssuer] set gpid [ACCESS::session data get session.saml.last.attr.name./GPID] Name of the cookie set cookie_name "xyz-JWT" set cookie header set cookie_header "[b64encode "{\r\n \"alg\": \"HS256\", \r\n \"typ\": \"JWT\"\r\n}"]" set cookie payload set cookie_payload "[b64encode "{\r\n \"user\": \"$user\",\r\n \"sub\": \"$sub\",\r\n \"nbf\": \"$nbf\",\r\n \"exp\": \"$exp\",\r\n \"email\": \"$email\",\r\n \"surname\": \"$surname\",\r\n \"givenname\": \"$givenname\",\r\n \"aud\": \"$aud\",\r\n \"gpid\": \"$gpid\"\r\n}"]" set cookie data for signatur set cookie_data [concat "[b64encode [URI::encode $cookie_header]].[b64encode [URI::encode $cookie_payload]]"] test some other version set cookie_data "[URI::encode [b64encode $cookie_header]]\".\"[URI::encode [b64encode $cookie_payload]]" set cookie_data "[URI::encode $cookie_header]\".\"[URI::encode $cookie_payload]]" set cookie_data $cookie_header"."$cookie_payload log local0. "cookie_data $cookie_data" create signatur set cookie_sig "[CRYPTO::sign -alg hmac-sha256 -key $secret_key $cookie_data]" convert signatur in some version set cookie_sig_b64 "[b64encode $cookie_sig]" set cookie_sig_b64_url "[URI::encode $cookie_sig_b64]" set cookie_sig_url_b64 "[b64encode $cookie_sig_url]" log local0. "sig_b64= $cookie_sig_b64" log local0. "sig_b64_url= $cookie_sig_b64_url" log local0. "sig_url_b64= $cookie_sig_url_b64" verify signatur if { [CRYPTO::verify -alg hmac-sha256 -key $secret_key -signature $cookie_sig $cookie_data] } { log local0. "Data verified" } create full JWT set cookie "$cookie_header.$cookie_payload.$cookie_sig_url_b64" HTTP::cookie insert name $cookie_name value $cookie log local0. "$cookie_name $cookie" } send to client when HTTP_RESPONSE { HTTP::cookie insert name $cookie_name value $cookie } If I verify the cookie with jwt.io (webseite). I get alway a signatur error. All other works. The json notation for signatur is HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret ) secret base64 encoded I think I have a mistake in format for cookie_data. In the version you can see some of my tests. How can help me? Cheers, NetSnoopy729Views0likes2Comments