Published on O'Reilly (http://oreilly.com/)
 See this if you're having trouble printing code examples

Cookie Specification Vulnerabilities

by Alexander Prohorenko

Why Do We Need Cookies?

The HTTP protocol is "disposable" in one sense. Each time the user requests a page, he begins all over again, no matter what he entered and which changes he made. There's no state to the protocol.

Cookies help to create the illusion that the site remembers a user. The user does not need to enter the same information from page to page or from session to session, because of the cookie stored on the user's disk. It is possible that the user can always edit or replace this information, too. A cookie can store various data -- for example, the quantity of page hits and their time. Cookies make it possible to create interesting web applications, such as a small organizer or a basket in virtual shop.

Cookie Insecurities

Many people dislike cookies because of their insecurity. However, many different analysts claim that there is no a problem, that it's absolutely impossible to make anything harmful with cookies. I deeply disagree: if someone can read the information from a cookie, it is already unsafe. I'll provide several theoretical examples that are easy to implement in reality.

  1. Suppose a user visits a webmail site and has filled in the form with his login and the password. These are stored in a cookie, though the site uses SSL. A burglar has emailed the user an HTML-formatted message with JavaScript capable of reading the cookie and its password, then tricking the user into sending the information to the burglar by popping up a false message such as "JavaScript Errors." This will even fool some experienced users into pressing OK and passing along the data. Alternately, the bad guy could add an invisible frame to hold cookie information at the bottom of the letter. This is all easy with HTML forms and a little JavaScript.

  2. Consider a web store at shop.provider.com. While making purchases in this shop, the site stores user information in a cookie. In parallel or before browsing the shop, the user browsed the attacker's page, hacker.provider.com, where malicious code could adjust the shop's cookie, changing the quantity of purchases, a name, the address, and anything else stored in the given cookie. It would be unpleasant to purchase unknowingly a few monitors for someone else, or to have your purchases sent to another user. This is a simple enough attack once you have a page in the second or third level of the shop's domain.

There are other similar ways to harm systems, including several different JavaScript tricks including removing all of your cookies.

Inside Cookies

Let's dig deeper into the technical workings of cookies. For Windows users, cookies live as multiple files in the folder %WINDOWS%\Cookies (by default in Internet Explorer) or as only one file, cookie.txt (if you have Netscape Navigator or other browsers). Sites periodically add or remove cookie information. Naturally, the cookie specifications stipulate some elements of protection.

When the browser reaches 300 cookies, it should throw out the earliest cookies. If a cookie exceeds 4kb, the browser should cut out the first bytes.

Cookie Format

Netscape maintains a full cookie specification. Describing it goes beyond this article, so I will include here only general information.

Cookies store information as VARIABLE = VALUE pairs. One document can consist of a few cookies (less than 20). The absolute minimum cookie description is:

Set-Cookie: NAME=VALUE;

A fuller cookie description is:

Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME;

Here are the fields and their explanations.

Inserting a Cookie into HTML

There are several ways to insert a cookie into HTML. The most simple is through a META-tag. Alternatives include JavaScript on the client-side, and every possible server-side technology such as CGI, PHP, and SSI. We will not consider client-side solutions, since they require the use of specific technologies that your hosting provider may not make available.

Using Cookies Through the META-tag

Here's an example of setting a cookie with a <META> tag:

<META HTTP-EQUIV="Set-Cookie" CONTENT="John=Hacker;
	expires= Mon, 29-Dec-2003 03:00:00 GMT; path=/; domain=extrasy.net; secure">

Using Cookies with JavaScript

This is the most popular way since it is simple enough for the developer, does not require any special server software, and can use dynamic data generated by JavaScript or entered by the user. Here is an example of JavaScript that applies those ideas:

<script language="JavaScript">
var username = GetCookie('username');

if (username == null) {
	username = prompt('Enter your name or click Cancel','');

	if (username == null) {
		alert('Okay, you will be GUEST');
		username = 'GUEST';
	} else {
		pathname = location.pathname;
		myDomain = pathname.substring(0, pathname.lastIndexOf('/')) +'/';

		var largeExpDate = new Date ();

		largeExpDate.setTime(largeExpDate.getTime() + (365 * 24 * 3600 * 1000));
		SetCookie('username', username, largeExpDate, myDomain);

function getCookieVal (offset) {
	var endstr = document.cookie.indexOf (";", offset);

	if (endstr == -1)
		endstr = document.cookie.length;

	return unescape(document.cookie.substring(offset, endstr));

function GetCookie (name) {
	var arg  = name + "=";
	var alen = arg.length;
	var clen = document.cookie.length;
	var i    = 0;

	while (i < clen) {
		var j = i + alen;
		if (document.cookie.substring(i, j) == arg)
			return getCookieVal (j);

		i = document.cookie.indexOf(" ", i) + 1;

		if (i == 0)
	return null;

function SetCookie (name, value) {
	var argv    = SetCookie.arguments;
	var argc    = SetCookie.arguments.length;
	var expires = (argc > 2) ? argv[2] : null;
	var path    = (argc > 3) ? argv[3] : null;
	var domain  = (argc > 4) ? argv[4] : null;
	var secure  = (argc > 5) ? argv[5] : false;

	document.cookie = name + "=" + escape (value) +
		((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +
		((path == null) ? "" : ("; path=" + path)) +
		((domain == null) ? "" : ("; domain=" + domain)) +
		((secure == true) ? "; secure"; : "");

document.write('<p align=center>Hello, ' + username + '</p>');
// --></SCRIPT>

Cookie Attacks

As one sub-domain can only have 20 cookies, it's possible to exceed this limit if you have access to such a server. Upload the following HTML file on the server that the victim will use, such as the free email server described above.

<META HTTP-EQUIV="Set-Cookie" CONTENT="John01=Hacker01;
	EXPIRES=Mon, 29-Dec-2004 03:03:03 GMT;">
<META HTTP-EQUIV="Set-Cookie" CONTENT="John02=Hacker02; EXPIRES=
	Mon, 29-Dec-2004 03:03:03 GMT;">

<META HTTP-EQUIV="Set-Cookie" CONTENT="John20=Hacker20;
	EXPIRES=Mon, Mon, 29-Dec-2004 03:03:03 GMT;">

Add at least 20 such records. Save this file as cook.htm; we will use it in other examples.

Another attack is to rewrite user cookies with empty or dummy data. This exploits the cookies specification's limit of only 300 cookies. For this attack, you need to register several sites on one of the numerous free hosting providers' domain names, such as hack.site1.net, hack.site2.net, etc. Place on each of them the above-mentioned cook.htm. The following index.html, uploaded to any free host, will attack the user and force the removal of all host cookies:

<frameset rows="0,0,0,0,0,0,0,0,0,0,0,0,0,0,*">
<frame scrolling="no" noresize target="hack.site1.net/cook.htm">
<frame scrolling="no" noresize target="hack.site2.net/cook.htm">
<frame scrolling="no" noresize target="hack.site15.net/cook.htm">

Another attack could force the user's browser to load and store a couple of megabytes of garbage cookie information. Depending on his connection, this could cause a disconnection.

	CONTENT="Data=You need to paste here 4kb of any trash data;
	EXPIRES= Mon, 29-Dec-2003 03:03:03 GMT;">

Cookie Status in Current Browsers

I would also like to provide a brief kick-test of the most popular browsers and the results of such cookie attacks. I've explored the browsers Internet Explorer, Netscape Communicator, Mozilla, and two console-only ones, Lynx and Links (which are mostly used on a Unix-running platforms).

The first attack produced expected results on all browsers. It is mostly not a technical attack, but a specification attack. However, it doesn't look to be very sensitive, as it will just render unavailable cookies for the specific domain. It could be fixed by disallowing cookies from non-authoritative sub-domains. Normally, it should not influence the work.

Moving forward, I've discovered that Netscape Communicator and Internet Explorer are not vulnerable to simple attacks, as described below. I did notice some strange cookie modifications by IE (in my tests it was Internet Explorer 5.00.2920.0000 with no Service Packs installed) during the attack of overloading the cookies cache with more then 300 cookies. Still, I suspect it's not vulnerable to such attacks.

As for text browsers Lynx and Links, I successfully attacked a cache of cookies using Lynx (2.8.4rel.1 from my sandbox) and Links (2.1pre11). From the other side, I can't say for sure that Lynx and Links are vulnerable browsers. Neither Lynx nor Links has a recently released version -- their releases are much like those I used for my tests. However, both of these browsers have development versions, and the results of attacks on the development versions differ greatly from the releases. I compromised the latest Lynx release version, which is 2.8.4, but the attack failed on the 2.8.5 dev 16, the latest available development version. I also failed to compromise Links browser links-2.1.pre14. This sounds like the developers are aware of security problems.

As for the Mozilla browser (Firebird from my sandbox) it also wasn't vulnerable, although it started swapping for about 30 to 60 seconds. I wasn't able to mention what changes have been made in the cache; everything kept working as it used to before the attacks.

To crown it all, I should say that the most modern and updated browsers are not vulnerable to simple cookie attacks, except for backdoors in the cookies specification. These are only fixable by good system-use policies.

Many of you may now say, "Oh, there is no need to worry about cookies now, my IE is not vulnerable!". But I've only performed tests for very, very simple cookie bugs. All these tests really indicate is that these browsers are pretty safe from kids' games, but not necessarily from professional attacks. If you refer to an archive of security papers devoted to cookies vulnerabilities of many versions of the different browsers, you won't feel so safe, although you will know better know what to protect yourself from.

Why did I consider only such simple attacks? Because of safety issues. I wanted to demonstrate vulnerability examples that are visible to any user merely familiar with the cookies specification. Unfortunately, there are many more complex ways to use cookies destructively. It's a pity, but there is no universal protection. If you disable cookies, you'll be locked out of many ubiquitous services. Installing additional programs to control and to supervise cookies can help, but it can be inconvenient.

Hopefully, a new cookie specification will soon emerge to provide the same useful service with more security. Until then, be careful.

Alexander Prohorenko is a certified professional, who holds Sun Certified System Administrator and Sun Certified Java Programmer certifications.

Return to the Security DevCenter.

Copyright © 2009 O'Reilly Media, Inc.