Checking if Cookies are Enabled

UPDATE: The information contained on this page is ancient and obsolete. Seek counsel elsewhere!


One of the uncertainties facing any web developer are the myriad browser configurations of different end-users. Some users may disable cookies due to fear that their personal information is being compromised, while the more security-paranoid may even disable JavaScript. This can pose a problem for web mechanisms that rely on cookies to store session identification and other neccessary information. Consequently, there may often be occasions where one wishes to check whether an end-user has cookies enabled. In this short article, I discuss the methods that can be used to check whether cookies are enabled, providing code samples.



The JavaScript Method

The simplest way to check for cookies is via JavaScript. The following function will return a boolean value -- true if cookies are enabled:

function are_cookies_enabled()
{
	var cookieEnabled = (navigator.cookieEnabled) ? true : false;

	if (typeof navigator.cookieEnabled == "undefined" && !cookieEnabled)
	{ 
		document.cookie="testcookie";
		cookieEnabled = (document.cookie.indexOf("testcookie") != -1) ? true : false;
	}
	return (cookieEnabled);
}

A snippet of code using the function above was executed when you loaded this page. The message below should notify you of your cookie status:

One of the disadvantages of the method above is that it requires JavaScript. Security-conscious end-users are often people who disable JavaScript as well as cookies. Thus, checking for the presence of cookies with JavaScript should be a supplementary method -- not one to be relied upon. For that, we need server-side checking in the CGI script(s).


The Standard Server-Side CGI Method

Your server-side scripting language of choice may vary, so I'll just stick to Perl for the purposes of this example, although the principle at work should be equally applicable to all server-side scripting languages. When a CGI program receives a request, it receives not only the CGI parameters (via the Query string or via STDIN, depending on wheter you use the GET or POST methods), but also an environment global variable. In Perl, this variable is accessed via the %ENV hash (associate array). Cookie data is stored in the environment hash by the key HTTP_COOKIE. Thus, to access raw cookie data, one would work with the scalar value $ENV{'HTTP_COOKIE'}.

Browsers with cookies disabled leave this environment key undefined. Thus, a simple snippet of code should suffice to check whether the end-user invoking the CGI script has cookies enabled:

#!/usr/bin/perl -w

print "Content-Type: text/plain\n\n";

if( !defined( $ENV{'HTTP_COOKIE'} ) )
{
    print "You have cookies DISABLED";
}
else
{
    print "You have cookies ENABLED";    
}

You can test this script here.

It is worth noting that this method, too, has its shortcomings. If the user has previously visited your site and received a cookie, this method will report the user as having cookies enabled, since the environment variable will contain data from his previous session -- this need not mean that the user has cookies enabled at the moment he calls your CGI script. This brings us to the final method, which is quite kludgy.

Setting and getting via CGI

The JavaScript example above tested for cookies by trying to set a cookie and then checking whether the newly set cookie existed. We can do the same with our server-side CGI script -- it isn't pretty, but it's guaranteed to work reliably under all circumstances. Again, I'll use Perl for purposes of demonstration.

First, we need to attempt to set some dummy cookie. We'll do this in our first CGI script, which I shall call cookie-set.pl. It will, in turn, redirect the end-user to our second script, cookie-check.pl

#!/usr/bin/perl -w

my $date;
# You should make the $date variable be a date 
# a few minutes from time of execution

print "Set-Cookie: my_website_dummy_test=1; expires=$date; path=/\n";
print "Content-Type: text/html\n\n";
print '<html><head><meta http-equiv="refresh" content="0;URL=/cgi-bin/cookie-check.pl"></head></html>';

Now, in the second script, we check whether the cookie was successfully set.

#!/usr/bin/perl -w

print "Content-Type: text/plain\n\n";
if (!defined($ENV{'HTTP_COOKIE'}) or $ENV{'HTTP_COOKIE'} !~ /my_website_dummy_test/)
{
    print "You have cookies DISABLED";
}
else
{
    print "You have cookies ENABLED";
}

You can test this checking mechanism for yourself by clicking this link.

This last method should be relatively foolproof -- I have had no problems making use of it on active, heavily used corporate websites that receive visitors from particularly security-sensitive people. That being said, if you wish to service the truly security-conscious, it is best to avoid cookies and employ the Hot Potato method instead.