Security and performance when using session and cookies
This article will examine how web site programmers can use cookies to store a user’s session state during and beyond a particular session. First we will be discussing what cookies are, what sessions are and why it is useful to store session state. Then we will be looking at different strategies for using cookies in ASP and PHP. Finally, we will finish ths article with a discussion about the strengths and weaknesses of using cookies, and offer an alternative.
This article is aimed at he beginning to intermediate web site programmer who may be struggling to fully utilize their web server, or who needs a backgrounder for the technologies available. Equally, the advanced internet user can use this article as an aid to judging the usefulness or otherwise of accepting cookies whilst browsing the web.
Some Terms and their Definitions
Cookies
A web page can attempt to set a cookie to any browser which is visiting. I say attempt, because the web page can not force a browser to accept a cookie at all. All browsers allow the user to deny cookies. This can often be done in a staged way, allowing the user a reasonably fine control over which web pages can set, and read cookies. So what is a cookie any way, and where did the name come from?
A cookie is a set of information, formatted in a predifened way, which web browsers can store when asked to by web server. The information stored may be a simple counter, counting the number of times the user has visited the site. It may contain the users login-name or even their password. Later I will be discussing why this is a security risk, and a bad idea. Cookies can be used to store whatever data the web server wishes to remember about the user. The thing about cookies which is often overlooked, is that the browser subsequently returns the cookie to the server on every request.
This is a bit like issuing a library card. The first time you visit a library they give you a membership ard, containing your name, age and whatever else the library would like to store there. When you return to the library in future, they expect you to bring your card along with you. In fact if you don’t, they may get irritated or rude. The membership card is like a cookie, it contains information. The web server issues cookies, much as a library issues membership cards. The browser returns the cookie with every subsequent request to the web server, just as you take your membership card back to the library on every further visit.
There are some more similarities: The amount of information that you can print on a library card is not limitless: cookies can be a maximum of 4 KB large. The library issues you with a card once, unless you loose it and they will give you a new one: cookies are often issued once every visit to a web site and are often updated. Library cards are issued directly to you, as are cookies.
Microsoft’s Internet Explorer distinguishes between first party cookies, third party cookies, and session cookies. All cookies look and feel exactly the same, so why the different treatment? First party cookies are returned to the server that created it. These are standard cookies, created by many web sites.
Third party cookies are created by a web site different to one that you are currently visiting. Imagine that the page you just requested contain 51 images. If you count them you may only reach 50, the 51st image is “invisible”, it is often a transparent gif just 1x1 pixel large. It is entirely possible that this pixel is a “web beacon”, it has been embedded by the page’s owner but is actuallly delivered by a completely different company, maybe double click. Because your browser has analyzed the contents of the page, and has sent a request for the web beacon to a totally different server, this server may also attempt to set a cookie, so that it can recognize you in future. Third party cookies are an important revenue source for many web sites, but you may choose to disable them.
Session cookies are temporarily stored and are deleted when the browser window(s) are closed. They often contain no data other than a cryptically long ID, known as a session ID. They usually serve only to identify your browser to the web server between requests, in essence a library card containing a uniquely generated number.
Cookies were originally proposed by Netscape, their reference document can
be accessed here:
http://www.netscape.com/newsref/std/cookie_spec.html.
Sessions
So why does the web server need to store this information in a cookie? Can’t
this be done on the server, using text files or databases or memory? Well,
yes and no. The communication between the web server and the web browser,
also known as the client, occurs using the HTTP protocol (
http://www.faqs.org/rfcs/rfc2616.html). This protocol is stateless.
When a web browser asks fo a page, let’s say index.html, the web server
returns the document asked for (assuming it can be found and has no security
protection). When the web browser then asks for a further page, lets say products.html,
the same process applies. Only that the webserver treats each request as being
completely separate, having nothing to do with each other, and not belonging
to any particular user. This is what the statelessness in HTTP means.
The web server can choose to store persistant information in a cookie. Since cookie data is returned with every request, the server can identify a particular browser using the contents of the cookie data. Not every web site needs to use sessions. But imagine going to an online store, and putting an item in the shopping basket. Everybody expects the item to still be there even if you continue looking at other items. Other web sites want to track which pages you’ve visited or which adverts have been shown to you, all of these examples require functioning sessions. Here it is important to note that not all cookies contain session information, they may contain your username which can be used across different sessions. Many web sites store nothing more than the session ID in the cookie. When the browser returns the ID, the server can recall the contains of stored session information from memory or from a database.
The use of cookies in maintaing session state is being standardized in RFC 2965:
http://www.faqs.org/rfcs/rfc2965.
Creating Cookies
On the server side, it is easy to create, read and delete cookies. Here’s how to do it:
Create a cookie illustrating the previous libraray example:
ASP:
<%
Response.Cookie (“MyLibrary”)(“MemberName”) = “Richard"
Response.Cookie (“MyLibrary”)(“MemberNumber”) = “123456789"
Response.Cookie (“MyLibrary).Expires = Date +1
%>
PHP:
<?PHP
setcookie ("MyLibraryMemberName", “Richard” ,time()+ (60*60*24),);
?>
Reading Cookies
Cookies are sent as part of the server’s response header, before HTML is sent. Because of this, cookies should be written before any HTML or other content is sent to the browser.
Reading a cookie is easy
ASP:
<%
userName = Request.Cookie (“MyLibrary”)(“MemberName”)
memberNumber = Response.Cookie (“MyLibrary”)(“MemberNumber”)
%>
PHP:
<?PHP
var userName = $_COOKIE[‘MyLibraryMemberName’];
?>
Destroying Cookies
Destroying cookies is also easy, we just set its expiry date to sometime in the past:
ASP:
<%
Response.Cookie (“MyLibrary”).Expires = Date -1
%>
PHP:
<?PHP
setcookie ("MyLibraryMemberName", “” ,time() - (60*60*24),);
?>
For more information on using cookies with ASP, see the definitive reference
at
http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b302390#References.
For more information on using cookies with PHP, see the PHP reference at
http://www.php.net/manual/en/function.setcookie.php.
Creating Sessions
As mentioned earlier, not every cookie stores session state. Cookies may be used to store session information, and in particular a uniqze ID assigned to each new session. So how do we create and end sessions on the server?
This is ridiculously simple using ASP:
<%
Session(“userName”) = “Richard”
%>
We have created a variable named “userName” which can be accessed from any other page. In the background, your webserver has created and sent a cookie, containg an session ID, to the browser.
Using sessions with PHP is a little more complicated, although the same basic principles apply:
<?PHP
if (!isset($_SESSION['userName'])) {
$_SESSION['userName'] = “Richard”;
} else {
$_SESSION['userName'] = “Richard”;
}
?>
In both examples, the web server has created a cookie and sent it to the browser. The cookie does not contain any clear text information, simply a single ID.
Reading Data from Sessions
Again, in ASP this operation is simple:
<%
userName = Session(“userName”)
%>
And in PHP:
<?PHP
var userName = $_SESSION['userName'];
?>
In both examples, the previously stored user name is read from the session storage and placed in a variable called userName, all without the coder having to manage cookies explicitly, the work is performed in the background.
Destroying Sessions
When you want to expire a session programatically, and not just let it run out of scope within the predfined time period, you can do this easily:
Again, in this operation is simple:
<%
Session.Abandon
%>
And in PHP:
<?PHP
session_destroy();
?>
In both examples, the session and the contents of any variables stored there are destroyed.
For a more complete backgrounder on using sessions in ASP, see this article
from Microsoft:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;175167.
Also see a more detailed explanation of PHP sessions here:
http://de2.php.net/manual/en/ref.session.php.
The Case Against Cookies
As we have seen, cookies are used to store information on the client between requests. The information stored can be a session ID, allowing sophisticated web servers to store any session data on the web server, and not put it on the client.
This is essential should we wish to store sensitive information such as passwords, credit card data, address or personal information throughout the lifetime of a user’s interaction with the web server. Cookie data is stored on the user’s machine, in an easily readable text file. Anyone with access to the machine can read the cookies contents. In the past, security holes in different browsers have also allowed malicious web sites to access the contents of cookies set by completely innocent web sites.
Historically, cookies have had very bad press. Even today, some companies use cookies or web beacons to track an individuals surfing habits, consolidate and analyze this data to provide a detailed picture of what you read, what you buy, your assumed education or income level. Because of these issues, many users choose to deactivate all cookies, with the intention of insulating themselves from prying eyes. There are better ways of doing this (by using a personal firewall, for instance), but the problem remains that not every one accepts cookies.
If you are running a community based web site which requires some form of active registration and continued participation to receive information or other benefits, this issue is often forced. Many such community sites expect the members to accept cookies, since they are in any case receiving a free service. On the other hand, sites which want to sell a product or service to as many customers as possible are well advised to find an alternative to cookies, allowing them to reach a much wider potential audience.
ASP.NET and PHP, as well as JSP, allow session IDs to be stored within the URL as opposed to within a cookie. When browsing some sites, you may already have noticed that a cryptically long ID is sent with every GET or POST request you send. This is simply the session ID, allowing the web server to keep track of which shopping basket belongs to you. On a more advanced note, it is a good idea to cascade your use of technologies. Use cookies as a default approach. When your web server encounters a browser which won’t accept them, degrade graciously to using IDs in the URL (this is known as URL rewriting).
Many issues arise from these solutions, such as keeping your pages bookmarkable by users and by allowing search engines to crawl your site and index the pages, without either cookies or URL rewriting. These issues are beyond the scope of this article, but the followig refereces are good starting points!

This work is licensed under a Creative Commons License.