Increased Security With First Party Cookies
HTTP cookies are an essential part of many web based applications, useful for tracking session and state information. But they can also be exploited to leak information to third party sites using a method known as Cross Site Request Forgery (CSRF). A CSRF attack takes advantage of the web browser behavior which results in cookies being sent to third party sites when a page contains mixed content. This results in cross-site information leakage, and depending on the content of the cookies, could provide an attacker with information to hijack a user session. SameSite Attribute As of this writing, there is a Internet draft standard for directing clients to only send ‘first party’ cookies. In a nutshell, the standard defines a new, backwards-compatible attribute for the Set-Cookie header named SameSite. When the SameSite attribute is present, compliant browsers will only send that cookie with requests where the requested resource and the top-level browsing context match the cookie. This becomes another layer of a “defense in depth” strategy, mitigating CSRF and cross-site script including (XSSI) attacks. SameSite is supported in recent Chrome and Firefox browsers. SameSite can be specified alone, or with explicit values “Strict” or “Lax”, corresponding to differing levels of lock-down. Specifying SameSite can increase security, but it is not appropriate for all applications. One example would be “mash-up” applications, those which intentionally pull and embed content from different sites, may require cross-site cookies to function correctly. Also, some single sign-on features may require cross-context authentication that involves cookies. So how can you secure your apps? Big IP provides 3 ways to add SameSite attribute to Set-Cookie headers, two of which are described below: iRules and LTM Policy. Mentioned in another article, the Application Security module also provides a setting to enable SameSite. iRule to add SameSite attribute Here is iRule which can handle multiple Set-Cookie headers in a response. If a Set-Cookie header already has SameSite attribute present, it is passed through unmodified. This allows an administrator to set a baseline security level, say by specifying “SameSite=Lax” in an iRule, but allows for individual apps to control their security level by generating headers with their own Set-Cookie header, with say “SameSite=Strict”. when HTTP_RESPONSE { # Set-Cookie header can occur multiple times, treat as list set num [HTTP::header count Set-Cookie] if {$num > 0} { foreach set_cookie [HTTP::header values Set-Cookie] { # only modify if header does not have SameSite attribute set foundSameSite [string match -nocase "*SameSite*" $set_cookie ] if {[expr {!$foundSameSite} ]} { set set_cookie [concat $set_cookie "; SameSite"] } # collect modified and unmodified values in list newcookies lappend newcookies $set_cookie } if {$num == 1} { # overwrite existing HTTP::header Set-Cookie [lindex $newcookies 0] } else { # remove and replace HTTP::header remove Set-Cookie foreach set_cookie $newcookies { HTTP::header insert Set-Cookie $set_cookie } } } } LTM Policy Below is a sample LTM Policy which will tag “; SameSite” to the end of a Set-Cookie header that doesn’t have one already. One limitation to be aware of is that there can be multiple Set-Cookie headers in an HTTP response, and LTM policy can only replace the last one. Here is a screenshot from the GUI showing an LTM Policy rule which Here is the resulting policy as it would appear in the /config/bigip.conf configuration file: ltm policy first-party-cookies { requires { http } rules { r1 { actions { 0 { http-header response replace name Set-Cookie value "tcl:[HTTP::header Set-Cookie]; SameSite" } } conditions { 0 { http-header response name Set-Cookie not contains values { SameSite } } } } } status published strategy first-match }8.1KViews1like16CommentsBack to Basics: The Many Faces of Load Balancing Persistence
Finally! It all makes sense now! Thanks to cloud and the very generic "sticky sessions", many more people are aware of persistence as it relates to load balancing. It's a critical capability of load balancing without which stateful applications (which is most of them including VDI, most web applications, and data analysis tools) would simply fail to scale. Persistence is, in general, like the many moods of Spock. They all look pretty much the same from the outside - ensure that a user, once connected, continues to be connected to the same application instance to ensure access to whatever state is stored in that instance. But though they act the same (and Spock's expression appears the same) deep down, where it counts, persistence is very different depending on how it's implemented. It requires different processing, different inspection, different data, even. Understanding these differences is important because each one has a different impact on performance. The Many Faces of Persistence There are several industry de facto standard types of persistence: simple, SSL, and cookie. Then there are more advanced forms of persistence: SIP, WTS, Universal and Hash. Generally speaking the de facto standard types of persistence are applicable for use with just about any web application. The more advanced forms of persistence are specific to a protocol or rely on a capability that is not necessarily standardized across load balancing services. Without further adieu, let's dive in! Simple Persistence Simple persistence is generally based on network characteristics, like source IP address. It can also include the destination port, to give the load balancer a bit more capacity in terms of simultaneously applications supported. Best practices avoid simple persistence to avoid reoccurrence of the mega-proxy problem which had a tendency to overwhelm application instances. Network load balancing uses a form of simple persistence. SSL Session ID Persistence SSL Session ID persistence became necessary when SSL was broadly accepted as the de facto means of securing traffic in flight for web applications. Because SSL sessions need to be established and are very much tied to a session between client and server, failing to "stick" SSL-secured sessions results in renegotiation of the session, which takes a noticeable amount of time and annoys end-users. To avoid unnecessary renegotiation, load balancers use the SSL Session ID to ensure sessions are properly routed to the application instance to which they first connected. Cookie Persistence Cookie persistence is a technique invented by F5 (shameless plug) that uses the HTTP cookie header to persist connections across a session. Most application servers insert a session id into responses that is used by developers to access data stored in the server session (shopping carts, etc... ). This value is used by load balancing services to enable persistence. This technique avoids the issues associated with simple persistence because the session id is unique. Universal Persistence Universal persistence is the use of any piece of data (network, application protocol, payload) to persist a session. This technique requires the load balancer to be able to inspect and ultimately extract any piece of data from a request or response. This technique is the basis for application-specific persistence solutions addressing popular applications like SIP, WTS, and more recently, VMware View. SIP, WTS, Username Persistence Session Initiation Protocol (SIP) and Windows Terminal Server (WTS) persistence are application-specific persistence techniques that use data unique to a session to persist connections. Username persistence is a similar technique designed to address the needs of VDI - specifically VMware View solutions - in which sessions are persisted (as one might expect) based on username. When a type of persistence becomes very commonly used it is often moved from being a customized, universal persistence implementation to a native, productized persistence profile. This improves performance and scalability by removing the need to inspect and extract the values used to persist sessions from the data flow and results in an application-specific persistence type, such as SIP or WTS. Hash Persistence Hash persistence is the use of multiple values within a request to enable persistence. To avoid problems with simple persistence, for example, a hash value may be created based on Source IP, Destination IP, Destination Port. While not necessarily unique to every session, this technique results in a more even distribution of load across servers. Non-unique value-based persistence techniques (simple, hash) are generally used with stateless applications or streaming content (video, audio) as a means to more evenly distribute load. Unique value-based persistence techniques (universal, application-specific, SSL ID) are generally used with stateful applications that depend on the client being connected to the same application instance through the session's life. Cookie persistence can be used with both techniques, provided the application is web based and uses HTTP headers for each request (Web Sockets breaks this technique).4.1KViews0likes1CommentLightboard Lessons: BIG-IP Cookie Persistence Values
The BIG-IP creates cookies (when enabled) in order to allow persistence. Several people have asked what these cookies look like and how their values are generated. This video digs into the details of cookie persistence values and how they are calculated. Enjoy! Related Resources: Overview of Cookie Persistence Overview of BIG-IP persistence cookie encoding Configuring BIG-IP Local Traffic Manager (LTM)606Views0likes10CommentsStop 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. -Joe387Views0likes0CommentsWho Took the Cookie from the Cookie Jar … and Did They Have Proper Consent?
Cookies as a service enabled via infrastructure services provide an opportunity to improve your operational posture. Fellow DevCentral blogger Robert Haynes posted a great look at a UK law regarding cookies. Back in May a new law went info effect regarding “how cookies and other “cookie-like” objects are stored on users’ devices.” If you haven’t heard about it, don’t panic – there’s a one-year grace period before enforcement begins and those £500 000 fines are being handed out. The clock is ticking, however. What do the new regulations say? Well essentially whereas cookies could be stored with what I, as a non-lawyer, would term implied consent, i.e. the cookies you set are listed along with their purpose and how to opt out in some interminable privacy policy on your site, you are now going to have to obtain a more active and informed consent to store cookies on a user’s device. -- The UK Cookie Law – Robert goes on to explain that the solution to this problem requires (1) capturing cookies and (2) implementing some mechanism to allow users to grant consent. Mind you, this is not a trivial task. There are logic considerations – not all cookies are set at the same time – as well as logistical issues – how do you present a request for consent? Once consent is granted, where do you store that? In a cookie? That you must gain consent to store? Infinite loops are never good. And of course, what do you if consent is not granted, but the application depends on that cookie existing? To top it all off, the process of gathering consent requires modification to application behavior, which means new code, testing and eventually deployment. Infrastructure services may present an alternative approach that is less disruptive technologically, but does not necessarily address the business or logic ramifications resulting from such a change. COOKIES as a SERVICE Cookies as a Service, a.k.a. cookie gateways, wherein cookie authorization and management is handled by an intermediate proxy, is likely best able to mitigate the expense and time associated with modifying applications to meet the new UK regulation. As Robert describes, he’s currently working on a network-side scripting solution to meet the UK requirements that leverages a full-proxy architecture’s ability to mediate for applications and communicate directly with clients before passing requests on to the application. Not only is this a valid approach to managing privacy regulations, it’s also a good means of providing additional security against attacks that leverage cookies either directly or indirectly. Cross-site scripting, browser vulnerabilities and other attacks that bypass the same origin policy of modern web browsers – sometimes by design to circumvent restrictions on integration methods – as well as piggy-backing on existing cookies as a means to gain unauthorized access to applications are all potential dangerous of cookies. By leveraging encryption of cookies in conjunction with transport layer security, i.e. SSL, organizations can better protect both users and applications from unintended security consequences. Implementing a cookie gateway should make complying with regulations like the new UK policy a less odious task. By centralizing cookie management on an intermediate device, they can be easily collected and displayed along with the appropriate opt-out / consent policies without consuming application resources or requiring every application to be modified to include the functionality to do so. AN INFRASTRUCTURE SERVICE This is one of the (many) ways in which an infrastructure service hosted in “the network” can provide value to both application developers and business stakeholders. Such a reusable infrastructure-hosted service can be leveraged to provide services to all applications and users simultaneously, dramatically reducing the time and effort required to support such a new initiative. Reusing an infrastructure service also reduces the possibility of human error during the application modification, which can drag out the deployment lifecycle and delay time to market. In the case of meeting the requirements of the new UK regulations, that delay could become costly. According to a poll of CIOs regarding their budgets for 2010, The Society for Information Management found that “Approximately 69% of IT spending in 2010 will be allocated to existing systems, while about 31% will be spent on building and buying new systems. This ratio remains largely the same compared to this year's numbers.” If we are to be more responsive to new business initiatives and flip that ratio such that we are spending less on maintaining existing systems and more on developing new systems and methods of management (i.e. cloud computing ) we need to leverage strategic points of control within the network to provide services that minimize resources, time and money on existing systems. Infrastructure services such as cookie gateways provide the opportunity to enhance security, comply with regulations and eliminate costs in application development that can be reallocated to new initiatives and projects. We need to start treating the network and its unique capabilities as assets to be leveraged and services to be enabled instead of a fat, dumb pipe. Understanding network-side scripting This is Why We Can’t Have Nice Things When the Data Center is Under Siege Don’t Forget to Watch Under the Floor IT as a Service: A Stateless Infrastructure Architecture Model You Can’t Have IT as a Service Until IT Has Infrastructure as a Service F5 Friday: Eliminating the Blind Spot in Your Data Center Security Strategy The UK Cookie Law –321Views0likes1CommentCloud Computing: Is your cloud sticky? It should be.
Load balancing an application should, by now, be a fairly routine scaling exercise. But too often when an application is moved into a load balanced architecture it breaks. The reason? Application sessions are often specific to an application server instance. The solution? Persistence, also known as sticky connections. The use of sessions on application servers to add state to web (HTTP) applications is a common practice. In fact, it's one of the greatest "hacks" in the history of the web. It's an excellent solution to the problem of using a stateless application protocol to build applications for which state is important. But sessions are peculiar to the application server instance on which they were created, and in general are not shared across multiple instances unless you've specifically achitected the application infrastructure to do so. Inserting applications into a load balanced environment often ignores this requirement, as load balancing decisions are often made based on server and application load and not on application specific parameters. THE PROBLEM When a client connects the first time, it's directed to Server A and a session is created. Data specific to the application that needs to be persisted over the session of the application, like shopping carts or search parameters, are stored in that session. When a client makes subsequent requests, however, the load balancer doesn't automatically understand this, and may direct the client to Server B, effectively losing the data in the session and hence breaking the application. This affects cloud computing initiatives because an integral part of cloud computing is load balancing to provide horizontal scalability and integral part of applications is session management. Deploying an application that works properly in a test environment into the cloud may break that application because the load balancing solution utilized by the cloud computing provider isn't aware of the importance of that session to the application and, too often, the session variables are unique to the application and the provider's static network infrastructure isn't capable of adapting to those unique needs. THE SOLUTION When choosing a cloud provider, it is imperative that the load balancing solution used by the provider support sticky connections (persistence) so that developers don’t have to rewrite or re-architect applications for cloud deployment. "Sticky connections", or persistence in the networking vernacular, ensure that client requests are load balanced to the appropriate server on which their application session resides. This maintains the availability of the session and means applications don't "break" when deployed into the cloud or inserted into a load balanced environment. Sticky (persistent) connections are often implemented in load balancers (application delivery controllers) by using application server session IDs to help make the decision on where requests should be sent. This results in consistent behavior and a well behaved application. The most common method of implementing sticky (persistent) connections is the use of cookie persistence. Cookie persistence inserts a cookie into the response that is later used to properly direct requests. The cookie often contains the JSESSIONID or PHPSESSIONID or ASPSESSIONID, but can actually contain any data that would allow the load balancer (application delivery controller) to identify the right application server for any given request. ACTION ITEMS If you are deploying applications into the cloud, or planning on doing so, and those applications are session sensitive, it is important that you determine before you deploy into the cloud whether or not your provider's solution supports sticky (persistent) connections, and how that persistence is implemented. Some solutions are not very flexible and will only provide persistence based on a limited array of variables and you will need to instrument your application to support the proper variables. Other solutions provide network-side scripting capabilities that will allow the provider - and you - to support persistence on any variable you deem unique enough to identify the proper application server instance. Note that server FQDN (fully qualified domain name) or IP address will likely not be adequate in a cloud computing environment as these variables may not be guaranteed to be static. The unique variable should ostensibly be something application specific, as this is likely the only variables you will have control over in the cloud and the only variables guaranteed to be consistent across instances as they are brought on and off-line in response to changes in demand. If you're currently examining the possibility of deploying applications in the cloud, make sure the cloud you choose is sticky to avoid the possibility that you'll need to rearchitect your application to get it to work properly.285Views0likes2Comments20 Lines or Less #18
What could you do with your code in 20 Lines or Less? That's the question I ask (almost) every week, and every week I go looking to find cool new examples that show just how flexible and powerful iRules can be without getting in over your head. Back with more cool examples of what iRules can do in a scant 20 lines of code, this week's 20LoL brings you three different HTTP goodies. Fully Decode URI http://devcentral.f5.com/s/Wiki/default.aspx/iRules/FullyDecodeURI.html This cool example from the wiki shows how you can ensure that your URI is not just decoded once, which can leave stray encoded characters behind, but that it's actually fully decoded. This is done with a while loop and a check to compare the decoded URI with the last pass. Take a look. when HTTP_REQUEST { # decode original URI. set tmpUri [HTTP::uri] set uri [URI::decode $tmpUri] # repeat decoding until the decoded version equals the previous value. while { $uri ne $tmpUri } { set tmpUri $uri set uri [URI::decode $tmpUri] } HTTP::uri $uri # log local0. "Original URI: [HTTP::uri]" # log local0. "Fully decoded URI: $uri"} HTTP Track Unanswered Requests If you're looking for a way to determine how many HTTP requests are still left open, or unanswered, then this is the iRule for you. In yet another great example of iRules power and brevity, this example provides some nice utility as well. when HTTP_REQUEST { STATS::incr StatsDemo inFlight if { [STATS::get StatsDemo inFlight] > [STATS::get StatsDemo inFlightMax] } { STATS::set StatsDemo inFlightMax [STATS::get StatsDemo inFlight] }}when HTTP_RESPONSE { STATS::incr StatsDemo inFlight -1} Cookie Encryption Gateway If you're looking to encrypt/decrypt ALL cookies going in and out of a virtual in one fell swoop, then here's your solution. Normal configuration of profiles requires you to state each cookie that's going to be encrypted. This iRule allows you to add or remove cookies from your application at will, while always being sure they're going to be secured. when RULE_INIT { # Exposed passphrase, but this key can be synchronized to the peer LTM set ::passphrase "secret" # Private passphrase, but it isn't synchronized. On LTM failover to # its peer, applications relying on the encrypted cookies will break. # set ::passphrase [AES::key]}when HTTP_REQUEST { foreach { cookieName } [HTTP::cookie names] { HTTP::cookie decrypt $cookieName ::passphrase }}when HTTP_RESPONSE { foreach { cookieName } [HTTP::cookie names] { HTTP::cookie encrypt $cookieName ::passphrase }} There they are, this week's 20 Lines or Less examples. This series has been awesome fun so far and I'm constantly impressed with the kinds of things that can be done in less than 21 lines of code. If you have any ideas, suggestions, comments, etc. please let me know. I'd love to hear your thoughts. Until next time, code hard. #Colin282Views0likes0Comments