Understand How the ASP.NET Cookieless Feature Works
Development Lead, Web Platform & Tools
Summary: There are many reasons that cookies may not be provided to your ASP.NET application—the user may have disabled them, or the browser may not support their use. This article outlines how the Cookieless feature can still provide cookie-like support to those users. (4 printed pages)
ASP.NET 2.0 introduces better support for devices that do not support cookies. This article attempts to demystify and explain in detail the inner working of how the ASP.NET core attempts to support cookies on such devices. Understanding how the system works is essential to grasp the (severe) limitations of this feature, and how to build Web applications that do not expose security holes through this feature. In a nutshell, this feature works in a fairly straightforward fashion: it takes the data that would normally go into the cookie, and stuffs it into the URL instead.
This article is structured in the following manner:
- First, we look at the features that provide "cookieless" support.
- Next, we look at the configuration settings that let you control this feature, and describe what the core engine does for each of these settings.
- Lastly, we go through the limitations of this feature and discuss the security concerns that you need to keep in mind when using this feature.
In earlier versions of ASP.NET (V1.0 and V1.1), the Session State feature was the only one that used the Cookieless feature. In V1.1 (and V1.0), the URL would look something like this:
http://MySite.com/MyWebApplication/(XXXXXXXXXXX)/home.aspx ^^^^^^^^^^^ Session ID
In V2.0, Anonymous Identification and Forms Authentication also use this feature. The URL may now look like this:
Breaking it down:
- A(XXXX): This is the Anonymous-ID. It is used to identify the (anonymous) user accessing your application. The string may or may-not be encrypted, depending on your configuration settings in the <anonymousIdentification> section.
- S(XXXX): This is the Session-ID (same as V1.1).
- F(XXXX): This is the Forms Authentication ticket.
For each of the above features (Forms Authentication, Anonymous Identification, and Session State), you can control if and when the cookiesless feature will be used, and when the cookieless feature will be used instead. The configuration setting controlling this is:
cookieless="UseCookies | UseUri | UseDeviceProfile | AutoDetect"
- "UseCookies": As this name implies, the cookieless feature will never be used.
- "UseUri": The cookieless feature will always be used.
- "UseDeviceProfile": Depending on the browser making the request, the cookieless feature may or may not be used. If ASP.NET recognizes that the browser does not support cookies, then the cookieless feature will be used. Technically speaking, the two Boolean variables Request.Browser.Cookies and Request.Browser.SupportsRedirectWithCookie must both be true for ASP.NET to assume that cookies are supported by the browser.
- "AutoDetect": In this setting, ASP.NET attempts to detect whether the browser supports cookies or not. The algorithm is a little complex, and I'll lay it out in pseudo code. (The algorithm is subject to change in future builds).
// Step 1: If the Browser configuration tells us definitively // that cookies are not supported, then report that and // exit immediately if ( !Request.Browser.Cookies || !Request.Browser.SupportsRedirectWithCookie) Report_cookies_are_NOT_supported_and_exit; // Step 2: Check if we have already detected that Cookies are not // supported. This is detected by looking for the string // "/(X(1))/" in the URL If (URL-contains-"/(X(1))/") Report_cookies_are_NOT_supported_and_exit; // Step 3: Check if client sent any (request) cookies if (Request.Headers["Cookie"] is not null or empty) Report_cookies_are_supported_and_exit; // Step 4: Check if this is a response to a challenge (sent in Step 5) // If this is a response to a challenge and no cookies were // sent (Step 3), then cookies are not supported If (Request.QueryString contains our AutoDetect challenge variable) Begin Insert "/(X(1))/" into the URI Report_cookies_are_NOT_supported_and_exit; End // Step 5: We can't detect if cookies are supported or not. So, send a // challenge to the client. We do this by sending a cookie, as // well as setting a query string variable, and then doing a // redirect back to this page. On the next request, if cookie // comes back, then Step 3 will report that "cookies are // supported". On the other hand, if the next request does not // have any cookies, then Step 4 will report "cookies not // supported". SetAutoDetectionCookie(); Redirect(ThisPage + Our_auto_detect_challenge_variable);
The principal limitation of this feature is the limited amount of data that can be stored in the URL. This feature is not targeted at common browsers such as IE, since these do support cookies and do not require this feature. The browsers that do not support cookies are the ones found on mobile devices (such as phones), and these browsers typically severely limit the size of the URL they support. So, be careful when you use this feature—try to make sure that the cookieless string generated by your application is small.
A second limitation on the size comes on the Windows 2003 platform. A (configurable) setting on the Windows Networking layer requires that each segment of the URL be less than 256 chars in length. Since the entire cookieless string goes into 1 segment, it must be less than 256 chars. (A segment of the URL is the portion of the URL between two forward slashes ('/')).
- Use an encrypted communication channel provided by SSL whenever an authentication cookie is transmitted.
- Use a cookie timeout to a value that forces authentication after a relatively short time interval. Although this doesn't prevent replay attacks, it reduces the time interval in which the attacker can replay a request without being forced to re-authenticate because the session has timed out.
One big issue that is unique to the cookieless feature (not present when using cookies), is the vulnerability linked to users sending URLs to other users (via Email and IM, for example). When this feature is turned on, for, say, FormsAuthentication, and the user emails his (or her) URL to some other user, the second user will automatically log on to the server with the credentials of the first user. One countermeasure is to reduce the time-window in which this can happen, by reducing the cookie timeout for forms authentication (as described previously in point (b)).