Dealing with Cookies has been a typical requirement of most web developers since the early days of the World Wide Web. In this article, after a brief introduction to explain how Cookies work in a typical web application, we will present some helper classes that allow you to implement the main activities necessary to manage Cookies in any ASP.NET project – Web Forms, MVC, and/or Core – in a rather simple way: we’re talking about reading, writing, editing and deleting functions, cookie key-value pairs management, and other useful features such as expiration date, domain restrictions, HttpOnly mode, Secure flag, and so on. In the last paragraph we will deal with how to configure the same settings and features at a global level, or rather in relation to all the cookies created by our web application, using the appropriate web.config file.

For those who do not know what HTTP cookies are – which would be suprising, if you came across this article – we refer you to our cookie policy page (which contains a brief explanation about the cookie general concept) and to the dedicated Wikipedia entry.

Introduction

Cookies perform a series of very important functions in most web applications. The most common cookie usage is the one involved in the user authentication phase using HTTP forms: authentication cookies are created by the server on the user’s computer at the time of login and contain the login that which can then be used – by subsequent visits – to detect a previous (successful) auth attempt and retrieve the required info to automatically perform the login. This data, depending on the case, may contain more or less delicate information, such as a hash of username and password, a timestamped authentication token and so on. For this reason it is extremely important to protect them from unauthorized access by following a series of standard security techniques, such as:

data encryption, or the encryption of personal data and values potentially subject to attack (username, password)

hashing of any password or security key that is not essential to transmit in clear text.

domain restrictions, by limiting the reading / writing permissions to a specific domain or sub-domain.

set the expiration date, in order to prevent the cookie from remaining stored indefinitely within the browser cache.

prevent access of client-side scripts trough the HttpOnly property: if enabled, this feature will ask the browser to hide the cookie from JavaScript and other client-side languages present on the page.

restrict the cookie activities to HTTPS connections only over secure SSL / TLS channels through the Secure flag; if enabled, this feature will prevent the cookie from being read and/or written from any eavesdropper that could intercept the communication flow between the client (browser) and the server (web application), thus mitigating most man-in-the-middle attacks and other common tampering-based threats.

Create a Cookie

The following static method, written in C# language, shows how to create a cookie on the user’s browser:

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

/// <summary>

/// Stores a value in a user Cookie, creating it if it doesn't exists yet.

/// </summary>

publicstaticvoidStoreInCookie(

stringcookieName,

stringcookieDomain,

stringkeyName,

stringvalue,

DateTime?expirationDate,

boolhttpOnly=false)

{

// NOTE: we have to look first in the response, and then in the request.

// This is required when we update multiple keys inside the cookie.

HttpCookie cookie=HttpContext.Current.Response.Cookies[cookieName]

??HttpContext.Current.Request.Cookies[cookieName];

if(cookie==null)cookie=newHttpCookie(cookieName);

if(!String.IsNullOrEmpty(keyName))cookie.Values.Set(keyName,value);

elsecookie.Value=value;

if(expirationDate.HasValue)cookie.Expires=expirationDate.Value;

if(!String.IsNullOrEmpty(cookieDomain))cookie.Domain=cookieDomain;

if(httpOnly)cookie.HttpOnly=true;

HttpContext.Current.Response.Cookies.Set(cookie);

}

As you can see by analyzing the parameters of the method, you can specify the cookie name, domain, expiration date and HttpOnly property: the Secureflag can be set globally within the web.config file, as we’ll seen later on, in order to make it globally enabled (or disabled) for all cookies generated by the site.

Create a Cookie with multiple values (using key-value pairs)

Each cookie represents, by definition, a single key-value pair: the keyis the name of the cookie, while the valueis just a plain, unencrypted, text string. This means that, under normal conditions, to pass multiple information – such as username, password and login date – you will need to create multiple cookies. Such way of proceeding might seem inefficient, especially if these values are linked together and there’s no need to grant the application independent access to each one of them: in such scenarios, it’s possible to use one of the many existing serialization standards to use a single cookie as a container of multiple key-value pairs, or a set of key-values.

The following implementation, written in C#language, takes care of that by using a standard Dictionary of strings:

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

/// <summary>

/// Stores multiple values in a Cookie using a key-value dictionary,

/// creating the cookie (and/or the key) if it doesn't exists yet.

/// </summary>

publicstaticvoidStoreInCookie(

stringcookieName,

stringcookieDomain,

Dictionary<string,string>keyValueDictionary,

DateTime?expirationDate,

boolhttpOnly=false)

{

// NOTE: we have to look first in the response, and then in the request.

Such technique makes possible to store real objects inside the cookie, provided that they their properties can be serialized into strings. At the same time, it is good not to overdo this approach, since the process of serialization and deserialization of cookies is certainly less efficient than the use of the same provided by the various specifications that define their operation (from the US5774670, published in 1998, to the RFC6265 currently in force).

Read a Cookie

The following static method, also written in C #, allows you to retrieve a string corresponding to the value of a single Cookie or – if we’re dealing with a key-value Cookie – to a single key within a single Cookie.

Check for Cookie existence

The last method we’re sharing can be useful to determine whether a cookie (or a given key-value pair within it) exists or not, without modifying it in any way.

C#

1

2

3

4

5

6

7

8

9

10

/// <summary>

/// Checks if a cookie / key exists in the current HttpContext.

/// </summary>

publicstaticboolCookieExist(stringcookieName,stringkeyName)

{

HttpCookieCollection cookies=HttpContext.Current.Request.Cookies;

return(String.IsNullOrEmpty(keyName))

?cookies[cookieName]!=null

:cookies[cookieName]!=null&& cookies[cookieName][keyName] != null;

}

Web Application Configuration

Now that we have seen how we can manage Cookies at the code level, it is time to take a look at the web.config file to understand how we can globally set some characteristics that will impact all the Cookies that will be created, modified or otherwise managed by our web application.

Secure Flag (requireSSL)

If we have configured our site to only accept web requests from protected channels (HTTPS with SSL / TLS certificate) it is certainly worth setting the Secure flag as active: before doing so, however, it is advisable to spend a couple of minutes to understand how it works.

The Secure flag, if present, instructs the browser to authorize the create feature (and in the most recent versions of browsers, even the read feature) of all our website’s cookies only if a secure connection has been estabilished. Unfortunately, most older browsers will allow the reading of Secure cookies even through unprotected connections, which is undoubtely a security issue: however, such behaviour can be strongly mitigated at the server level by allowing only protected connections and refusing (or redirecting via special HTTP rewrite / redirect rules to HTTPS) those coming from unsafe channels; anyway, using the Secure flag is still a great deal since it will help us to shield our “precious” authentication cookies from tampering attacks and/or other malicious activities performed by a potential man-in-the-middle ( MITM), preventing the cookie from being taken over or altered in any way.

To set the Secure flag globally, enter the following configuration parameters in the web.config file:

XHTML

1

2

3

4

5

6

<configuration>

<system.web>

<!-- Force secure connections for all Cookies -->

<httpCookies requireSSL="true" />

</system.web>

</configuration>

IMPORTANT: as long as the Secure flag is on, the application won’t create any cookie (including session ones) if executed through insecure, non-HTTPS channel: this will most likely affect any debug session, raising authentication errors and/or a ValidateTokens Exception (as explained in this post). To avoid these issues, it could be wise to set requireSSL=true through a transformation rule within the web.Release.config file, so that the Secure flag will be set only on published release builds.

If our web application is using Forms Authentication or other form-based authentications, the Secure flag should also be set in the configuration part of the aforementioned forms in order to prevent the authentication cookies from inheriting the settings (by default not secure) of the Form Authentication feature. To handle such scenarios, enter the following configuration parameters in the web.config file in addition to the previous ones:

XHTML

1

2

3

4

5

6

7

8

<configuration>

<system.web>

<authentication mode="Forms">

<!-- Force secure connections for Forms Authentication -->

<forms requireSSL="true" />

</authentication>

</system.web>

</configuration>

IMPORTANT: Regardless of the mode of transmission and the presence of the Secure flag, it is really important to keep in mind how the cookie is an intrinsically insecure data exchange & data storage method, since its content – even if received through a TLS secure channel – will always be read in memory and stored in the client’s cache as a plain, unencrypted text string. For this very reason, any sensitive data should still be protected by hashing or encryption techniques – which we’ll discuss in a upcoming post.

HttpOnly Flag

As already explained above, the HttpOnly flag – which is not active by default – tells the browser to hide Cookies from all client-side scripts, such as JavaScript. To force the activation of this flag at global level – which means, for all cookies created by our web application – you need to configure the httpOnly = “true” attribute in the web.config file in the following way:

XHTML

1

2

3

4

5

6

<configuration>

<system.web>

<!-- Prevent client-side scripts from reading Cookies -->

<httpCookies httpOnlyCookies="true" />

</system.web>

</configuration>

Domain restrictions

The domain restrictions, which we have already discussed above, can also be set globally by configuring the web.config file as follows:

XHTML

1

2

3

4

5

6

<configuration>

<system.web>

<!-- Prevent access to cookies from any external domain -->

<httpCookies domain=".mywebsite.com" />

</system.web>

</configuration>

Conclusion

That’s it, at least for the time being: we hope that this simple guide to ASP.NET Cookies will be useful to all developers and system administrators called upon to tackle these problems. Happy development!

Post navigation

About Ryan

IT Project Manager, Web Interface Architect and Lead Developer for many high-traffic web sites & services hosted in Italy and Europe. Since 2010 it's also a lead designer for many App and games for Android, iOS and Windows Phone mobile devices for a number of italian companies. Microsoft MVP for Development Technologies since 2018.

One Comment on “How to read, write, modify and delete Cookies in ASP.NET C#A brief tutorial illustrating how to manage Cookies in ASP.NET Web Forms, MVC and Core with examples of code in C Sharp language”

This is an awesome post.Really very informative and creative contents. These concept is a good way to enhance the knowledge.I like it and help me to development very well.Thank you for this brief explanation and very nice information.Well, got a good knowledge.