Return to HomePage



Setting application and ASP.NET 2.0 cookies securely (C#)



Applies to

* ASP.NET 2.0
* C#

Summary

This code illustrates the use of secure cookie modes within both application cookies and the ASP.NET session identifier cookie. Properly setting modes and attributes for application cookies is often vital in protecting against session hijacking.


Objectives

* Provide confidentiality of application cookies, ensuring that they are not exposed to unauthorized users which may often lead to session hijacking
* Restricting access to both application cookies and ASP.NET session identifiers to HTTPS
* Limit cookie scope to only desired applications and use scenarios
* Prevent cookies from being accessible from JavaScript (which can lead to session hijacking in the presence of cross-site scripting

Scenarios

* Cookies are used to maintain a session state
* Application uses cookies (either internal ASP.NET session id, or application specific cookies) and collects information from user such as authentication, or other form data at some point during session lifetime.
* Application requires SSL, but also is configured with an HTTP instance.

Solution Example


  • Scenario #1: HTTP alone is configured and multiple applications deployed on host (Restricting Cookie Path Example)*


		    protected void [SetAppCookie(string] name, string value, string path)
		    {
		        [HttpCookie] appCookie = new [HttpCookie(name);]
	

		        // Provide a specific path under which our cookies are permitted
		        // to be accessed
		        // 
		        // Application paths should be as specific as possible:
		        //  a sample application path might be: /secure/
		        appCookie.Path = path;
	

		        // The following cookie setting ensures that cookies are not made available within client-side
		        // script code thus mitigating the risk of unsafe access through attacks such as XSS.
	

		        // This feature is generally available in versions of Internet Explorer 6 and above
		        [appCookie.HttpOnly] = true;
	

		        // Set our cookie value
		        appCookie.Value = value;
		        Response.Cookies.Add(appCookie);
		    }
	

		 With Page_Load containing the following code
	

		    protected void Page_Load(object sender, [EventArgs] e)
		    {
	
...
		        SetAppCookie("GUID", [Guid.NewGuid().ToString(),] "/secure/");
	
...
		    }
	

  • Scenario #2: HTTP alone is configured and multiple applications need to share cookie values (Restricting cookie domain example)*


The following example assumes our application is deployed on www.codesamples.microsoft.com and we need to set a cookie that will be accessible from secure.codesamples.microsoft.com

		    protected void [SetAppCookie(string] name, string value, string path, string domain)
		    {
		        [HttpCookie] appCookie = new [HttpCookie(name);]
	

		        // Provide a specific path under which our cookies are permitted
		        // to be accessed
		        // 
		        // Application paths should be as specific as possible:
		        //  a sample application path might be: /secure/
		        appCookie.Path = path;
	

		        // The following cookie setting ensures that cookies are not made available within client-side
		        // script code thus mitigating the risk of unsafe access through attacks such as XSS.
	

		        // This feature is generally available in versions of Internet Explorer 6 and above
		        [appCookie.HttpOnly] = true;
	

		        // Set our cookie domain. This should only be used when applications deployed
		        // in a particular domain need to share values for some purpose (E.g. single sign-on)
		        appCookie.Domain = domain;
	

		        // Set our cookie value
		        appCookie.Value = value;
		        Response.Cookies.Add(appCookie);
		    }
	

		 With Page_Load containing the following code
	

		    protected void Page_Load(object sender, [EventArgs] e)
		    {
	
...
		        SetAppCookie("GUID", [Guid.NewGuid().ToString(),] "/secure/", ".codesamples.microsoft.com");
	
...
		    }
	


  • Scenario #3: HTTP and HTTPS co-exist on same host, users must login under HTTPS instance*
The following example assumes a site primarily for use under HTTPS with a welcome page deployed under HTTP. From the landing page users are redirected to the SSL site instance for login and the remainder of their session.

		    protected void [SetAppCookie(string] name, string value, string path, string domain, bool httponly, bool secure)
		    {
		        [HttpCookie] appCookie = new [HttpCookie(name);]
	

		        // Provide a specific path under which our cookies are permitted
		        // to be accessed
		        // 
		        // Application paths should be as specific as possible:
		        //  a sample application path might be: /secure/
		        if (path != null)
		        {
		            appCookie.Path = path;
		        }
	

		        // The following cookie setting ensures that cookies are not made available within client-side
		        // script code thus mitigating the risk of unsafe access through attacks such as XSS.
	

		        // This feature is generally available in versions of Internet Explorer 6 and above
		        [appCookie.HttpOnly] = httponly;
	

		        // The secure cookie mode ensures that cookies are set with the "secure" mode cookie flag,
		        // which makes cookies unavailable through standard HTTP. On sites where both HTTP and HTTPS
		        // is enabled non-secure cookies may be leaked in the event a user browses to the non-HTTPS
		        // instance of the site.
		        appCookie.Secure = secure;
	

		        // Set our cookie domain. This should only be used when applications deployed
		        // in a particular domain need to share values for some purpose (E.g. single sign-on)
		        if (domain != null)
		        {
		            appCookie.Domain = domain;
		        }
	

		        // Set our cookie value
		        appCookie.Value = value;
		        Response.Cookies.Add(appCookie);
	

		    }
	

		 With Page_Load containing the following code
	

		    protected void Page_Load(object sender, [EventArgs] e)
		    {
	
...
// We need not set the application host as it will default to the current host
SetAppCookie("GUID", Guid.NewGuid().ToString(), null, null, true, true);
...
		    }
	

Problem Example


Scenario #1: HTTP alone is configured and multiple applications deployed on host (Restricting Cookie Path Example)

The following example demonstrates setting a cookie without a default path value:

		        Guid guid = [Guid.NewGuid();]
		        [HttpCookie] chocolateChip = new HttpCookie("GUID");
	

		        // Set our cookie value
		        chocolateChip.Value = [guid.ToString();]
		        Response.Cookies.Add(chocolateChip);
	

* In the event that Cross-site scripting exists within the deployed application, a user's session may be hijacked as the cookie wasn't set with the HttpOnly cookie flag which limits access to the cookie within client scripting languages such as JavaScript and VBScript
* Cookies are set in the context of /, meaning any site deployed on the same virtual host may access values stored by our application deployed in /secure/
* Cross-site scripting, if present on other pages outside of our application directory deployed on the same virtual host may be used to hijack a user's session through luring attacks.

  • Scenario #2: HTTP alone is configured and multiple applications need to share cookie values (Restricting cookie domain example)*
The following example demonstrates setting a cookie without an overly permissive
domain value:

		        Guid guid = [Guid.NewGuid();]
		        [HttpCookie] chocolateChip = new HttpCookie("GUID");
		        chocolateChip.Domain = ".microsoft.com";
	

		        // Set our cookie value
		        chocolateChip.Value = [guid.ToString();]
		        Response.Cookies.Add(chocolateChip);
	

* In the event that Cross-site scripting exists within the deployed application, a user's session may be hijacked as the cookie wasn't set with the HttpOnly cookie flag which limits access to the cookie within client scripting languages such as JavaScript and VBScript
* Cookies are set in the context of .microsoft.com, meaning any site such as xss.microsoft.com, which may contain application vulnerabilities will be able to access cookies set by our application potentially leading to session hijacking.
* Cookies should be set to a domain which is as restrictive as possible. If two applications must share cookie values it may be beneficial to provision a dedicated sub-domain for use by the application servers.

Scenario #3: HTTP and HTTPS co-exist on same host, users must login under HTTPS instance
The following example demonstrates setting a cookie which fails to get set using the secure cookie flag.

		        Guid guid = [Guid.NewGuid();]
		        [HttpCookie] chocolateChip = new HttpCookie("GUID");
	

		        // Set our cookie value
		        chocolateChip.Value = [guid.ToString();]
		        Response.Cookies.Add(chocolateChip);
	

* In the event that Cross-site scripting exists within the deployed application, a user's session may be hijacked as the cookie wasn't set with the HttpOnly cookie flag which limits access to the cookie within client scripting languages such as JavaScript and VBScript
* Cookies are not set using the secure cookie flag potentially leading to session hijacking. In the event a user has bookmarked or visits the HTTP instance of the site after he/she has logged in, their session identifier will be sent in the clear to the web server. An eavesdropper who intercepts the communication may use the session cookie to bypass authentication and hijack the victim's session.

Test Case

The following classes must be included in any project making use of the sample code provided above:

using System.Web;

Please refer to Solution examples for invoking the SetAppCookie method depending on the scenario that best meets the application need.

Expected Result

The following expected results may be observed by monitoring the raw TCP connection:

Scenario 1 - HTTP response (Restricting Cookie Path)
Solution
		 	Set-Cookie: GUID=3de49a03-9957-4a37-ae37-bd3be473b9cf; path=/secure/; [HttpOnly]
	

Problem
		 	Set-Cookie: GUID=459d96d9-4b96-4251-9fcf-82a7a769d2f8; path=/
	

  • Scenario 2 - HTTP response (Restricting cookie domain, but requires sharing cookies between hosts)*
Solution
Set-Cookie: GUID=4453386a-92b1-4e95-a8d7-99e5b828ebcd; domain=.codesamples.microsoft.com; path=/secure/; HttpOnly

Problem
Set-Cookie: GUID=173705aa-a1cc-494b-92f3-e83cd0e8fe30; domain=.microsoft.com; path=/

''' Scenario 3 - HTTP response (Restricting cookie to SSL only)
Solution:
Set-Cookie: GUID=e4eeedb4-c3a1-44bb-af11-251c3cb10c37; secure; HttpOnly

Problem:
Set-Cookie: GUID=7328f6ba-ad56-4327-9cbd-ae4c8e516d17; path=/




More Information

In addition to solution 3, it may be advantageous to set the ASP.NET session cookie securely when it is used to maintain session state for the application

The "secure" and "httponly" cookie flags may be set within the ASP.net web.config file for the specific site in consideration. When relying on the ASP.NET built-in session object it is important to ensure both application and application server cookies operate similarly. As such the following code sample from a web.config demonstrates setting the ASP.NET session identifier with the "secure" mode and "httponly" cookie flags:

		    <!-- The following configuration entry ensures that the ASP.NET session identifier is set
		         within the context of a specified domain (ensure that the domain is a fully qualified host
		         whenever possible.
	

		         [httpOnlyCookies] ensures that cookies are unavailable to client script code 
		         [(JavaScript/VBScript).] This functionality is provided by newer web browser software
		         including Internet Explorer 6 and above
	

		         requireSSL ensures that the ASP.NET session cookie is not transmitted in the clear when
		         a user accesses the site via the plaintext HTTP instance of the site. -->
		    <httpCookies domain="codesamples.microsoft.com"
		                 httpOnlyCookies="true"
		                 requireSSL="true"/>
	


Additional Resources

* HTTP Request Cookies Class: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwebhttprequestclasscookiestopic.asp
* HTTP Cookies: http://msdn.microsoft.com/library/en-us/wininet/wininet/http_cookies.asp
* Cookie Members: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemnetcookiememberstopic.asp
* Mitigating Cross-site Scripting with HttpOnly cookies: http://msdn.microsoft.com/workshop/author/dhtml/httponly_cookies.asp

Attributes

* Applies To: .NET Framework 2.0, C#, ASP.NET 2.0
* Category: Session Management
* Author: George Gal





Return to HomePage
Microsoft Communities