Click here to Skip to main content
15,881,938 members
Articles / Programming Languages / C#
Article

Cookie Quest: A Quest to Read Cookies from Four Popular Browsers

Rate me:
Please Sign up or sign in to vote.
4.89/5 (11 votes)
14 Feb 2012CPOL7 min read 99K   9.4K   27   23
This article describes methods for reading cookies from Internet Explorer, FireFox, Chrome, and Opera.
Article_src

Contents

Introduction

The meeting was a short one. "Marketing has decided that the deployed application should self register via a web service once it is downloaded and launched the first time." The boss announced. "We'll write a cookie with an id field that will link the application to the record from the download page. The first time the application launches, it shall read this cookie and register via the web service." After a short pause, he continued. "Your mission, should you choose to accept it, is to get the cookie from whatever browser the customer is using and make it work."

Thus I embarked on a quest to find four cookie jars and to discover the secret of extracting a cookie from each one. Each successive cookie jar in this quest was more difficult than the previous one to crack. Here is an account of that quest.

Internet Explorer

Internet Explorer stores cookies in plain text files on the file system. In fact, to see them, open Internet Explorer and navigate to: Tools>Internet Options>General Tab>[Browsing history group]Settings> ViewFiles and you will see a directory full of cookies mixed in with a lot of other stuff. Go ahead open one and take a look.

Demo screenshot

Hmm... there's something strange going on here. Look at the filename in the title bar; MQNANRD2.txt doesn't match Cookie:dmacdermot@www.codeproject.com/. Well it turns out that these files are only a sort of cookie shortcut and this folder is not the real cookie jar! Furthermore, the real cookie is tucked away in a file with a cryptic name so you won't be able to use a file search to find it.

I determined that to get the cookie and value from Internet Explorer, I had to do the following:

  • Find where the cookies were stored in the file system.
  • Search the contents of each file in the directory for the desired cookie/hostname.
  • Once found, search that file for the desired field tag and then read out the value.

Here is the code to do just that:

C#
private static bool GetCookie_InternetExplorer
    (string strHost, string strField, ref string Value)
{
    Value = string.Empty;
    bool fRtn = false;
    string strPath, strCookie;
    string[] fp;
    StreamReader r;
    int idx;

    try
    {
        strField = strField + "\n";
        strPath = Environment.GetFolderPath(Environment.SpecialFolder.Cookies);
        Version v = Environment.OSVersion.Version;

        if (IsWindows7())
        {
            strPath += @"\low";
        }

        fp = Directory.GetFiles(strPath, "*.txt");

        foreach (string path in fp)
        {
            idx = -1;
            r = File.OpenText(path);
            strCookie = r.ReadToEnd();
            r.Close();
            
            if(System.Text.RegularExpressions.Regex.IsMatch(strCookie, strHost))
            {
                idx = strCookie.ToUpper().IndexOf(strField.ToUpper());
            }
            
            if (-1 < idx)
            {
                idx += strField.Length;
                Value = strCookie.Substring(idx, strCookie.IndexOf('\n', idx) -idx);
                if (!Value.Equals(string.Empty))
                {
                    fRtn = true;
                    break;
                }
            }
        }
    }
    catch (Exception) //File not found, etc...
    {
        Value = string.Empty;
        fRtn = false;
    }

    return fRtn;
}

Google Chrome

I navigated to Chrome's cookie manager by opening the browser and clicking the Wrench. Then choosing Options and in the newly opened tab selecting Under the hood. In the privacy group, I clicked Content Settings... Under Cookies, I selected All cookies and site data... and viewed a clickable list of cookies. This was all well and good but it didn't give me any clue as to where Chrome stored the actual cookies. So I Googled it!

It turns out that Google stores cookies in a SQLite3 database buried several layers down inside your LocalApplicationData folder of your profile. On an XP system, the path would be something like this: C:\Documents and Settings\[User Name]\Local Settings\Application Data\Google\Chrome\User Data\Default\Cookies. However, it is going to be different with later versions of Windows.

Here is the code I came up with to find it every time (hopefully).

C#
private static string GetChromeCookiePath()
{
    string s = Environment.GetFolderPath(
        Environment.SpecialFolder.LocalApplicationData);
    s += @"\Google\Chrome\User Data\Default\cookies";

    if (!File.Exists(s))
        return string.Empty;

    return s;
}

Now that I found the cookie jar, I just had to get inside and find my cookie. Fortunately for me, I had already used SQLite extensively and already had the tools at hand to easily crack this nut. I included the ADO.NET adapter for SQLite, System.Data.SQLite [^], in my project and coded my way in. Here's the method I used:

C#
private static bool GetCookie_Chrome(string strHost, string strField, ref string Value)
{
    Value = string.Empty;
    bool fRtn = false;
    string strPath, strDb;

    // Check to see if Chrome Installed
    strPath = GetChromeCookiePath();
    if (string.Empty == strPath) // Nope, perhaps another browser
        return false;

    try
    {
        strDb = "Data Source=" + strPath + ";pooling=false";

        using (SQLiteConnection conn = new SQLiteConnection(strDb))
        {
            using (SQLiteCommand cmd = conn.CreateCommand())
            {
                cmd.CommandText = "SELECT value FROM cookies WHERE host_key LIKE '%" +
                    strHost + "%' AND name LIKE '%" + strField + "%';";

                conn.Open();
                using (SQLiteDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        Value = reader.GetString(0);
                        if (!Value.Equals(string.Empty))
                        {
                            fRtn = true;
                            break;
                        }
                    }
                }
                conn.Close();
            }
        }
    }
    catch (Exception)
    {
        Value = string.Empty;
        fRtn = false;
    }
    return fRtn;
}

Mozilla Firefox

In order to find Firefox cookies, I opened Firefox and navigated to: Tools>Options>Privacy tab>Show Cookies. Open popped a nice cookie manager that again hinted at another database storage solution. A little searching confirmed my suspicion and lo: SQLite again!

I duplicated the method I used to find the Chrome cookie jar and modified it to find the one for Firefox. Here is the resulting method:

C#
private static string GetFireFoxCookiePath()
{
    string s = Environment.GetFolderPath(
                     Environment.SpecialFolder.ApplicationData);
    s += @"\Mozilla\Firefox\Profiles\";

    try
    {
        DirectoryInfo di = new DirectoryInfo(s);
        DirectoryInfo[] dir = di.GetDirectories("*.default");
        if (dir.Length != 1)
            return string.Empty;

        s += dir[0].Name + @"\" + "cookies.sqlite";
    }
    catch (Exception)
    {
        return string.Empty;
    }

    if (!File.Exists(s))
        return string.Empty;

    return s;
}

Notice the line:

C#
DirectoryInfo[] dir = di.GetDirectories("*.default");

Firefox is a bit more tricky in burying the location of the cookie file. In my case, the path turned out to be: C:\Documents and Settings\[User Name]\Application Data\Mozilla\Firefox\Profiles\cig7kfll.default\cookies.sqlite. Now cig7kfll could be anything, but fortunately there is only one such folder in this branch of the tree. I hope it stays that way.

The next thing I tried to do was open the cookie jar as I had done previously with Chrome. No luck... I was locked out! It turns out that FireFox locks this file while the browser is open so in order to read it, I had to take the following steps:

  • Copy cookies.sqlite to a temporary file.
  • Open and perform a SQL query on the temporary file to get my cookie.
  • Close and delete the temporary file.

Here is the code to do just that:

C#
private static bool GetCookie_FireFox(string strHost, string strField, ref string Value)
{
    Value = string.Empty;
    bool fRtn = false;
    string strPath, strTemp, strDb;
    strTemp = string.Empty;

    // Check to see if FireFox Installed
    strPath = GetFireFoxCookiePath();
    if (string.Empty == strPath) // Nope, perhaps another browser
        return false;

    try
    {
        // First copy the cookie jar so that we can read the cookies 
        // from unlocked copy while
        // FireFox is running
        strTemp = strPath + ".temp";
        strDb = "Data Source=" + strTemp + ";pooling=false";

        File.Copy(strPath, strTemp, true);

        // Now open the temporary cookie jar and extract Value from the cookie if
        // we find it.
        using (SQLiteConnection conn = new SQLiteConnection(strDb))
        {
            using (SQLiteCommand cmd = conn.CreateCommand())
            {
                cmd.CommandText = "SELECT value FROM moz_cookies WHERE host LIKE '%" +
                    strHost + "%' AND name LIKE '%" + strField + "%';";

                conn.Open();
                using (SQLiteDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        Value = reader.GetString(0);
                        if (!Value.Equals(string.Empty))
                        {
                            fRtn = true;
                            break;
                        }
                    }
                }
                conn.Close();
            }
        }
    }
    catch (Exception)
    {
        Value = string.Empty;
        fRtn = false;
    }

    // All done clean up
    if (string.Empty != strTemp)
    {
        File.Delete(strTemp);
    }
    return fRtn;
}

Opera

In order to find Opera cookies, I opened Opera and navigated to: Opera button>Settings>Preferences>Advanced Tab. I then selected Cookies from the list and clicked Manage Cookies... Again, I encountered a nice cookie manager and so I Googled the location of the file itself. My efforts yielded the following method for locating the Opera cookie jar.

C#
private static string GetOperaCookiePath()
{
    string s = Environment.GetFolderPath(
        Environment.SpecialFolder.ApplicationData);
    s += @"\Opera\Opera\cookies4.dat";

    if (!File.Exists(s))
        return string.Empty;

    return s;
}

Now any file ending with a .dat extension does not bode well. I had a suspicion that the file was saved in some kind of proprietary format but mustering hope, I attempted to open it with my trusty SQLite viewer. No luck. Next, I applied the Hex editor. Suspicion confirmed. Being somewhat lazy and hoping beyond hope that someone had attempted a parser for this file before, I hunted the dark corners of the World Wide Web. After much sleuthing, I found a solution! But wait, what's this? Alas, it was all written in Delphi!

Great minds write great software in Delphi, any time I have wanted some obscure snippet, something beyond the common stuff that you can find just about anywhere, invariably it is written in Delphi. I have also played around with many freeware Delphi translators and come to one conclusion: the only Delphi translator that really works is the one between my ears.

Having never learned Delphi or Pascal, I first scanned the source code looking for code patterns and elements of structure, then typed them into C# equivalents making a number of educated guesses along the way but not trying to really understand anything yet. This resulted in a bunch of pseudo C# code that was more familiar to my eyes. I went through this pseudo code, method by method, and began to turn it into actual C# code. I began to recognize what was going on at this stage, so I only needed a third pass over the source, mostly refactoring, to polish off the file parser.

In addition to the Delphi solution, I found some links to some helpful technical documentation[^] as well as Opera's Technical documentation [^]. In a nut shell; Opera stores cookies in a domain tree that can be recursively searched and compactly stored. As illustrated in the following diagram:

Demo screenshot

The actual cookies (or cookie fields) hang like apples on the tree.

Ok. So after that ordeal, I composed the following method to read the opera cookie:

C#
private static bool GetCookie_Opera(string strHost, string strField, ref string Value)
{
    Value = "";
    bool fRtn = false;
    string strPath;

    // Check to see if Opera Installed
    strPath = GetOperaCookiePath();
    if (string.Empty == strPath) // Nope, perhaps another browser
        return false;

    try
    {
        OpraCookieJar cookieJar = new OpraCookieJar(strPath);
        List<O4Cookie> cookies = cookieJar.GetCookies(strHost);

        if (null != cookies)
        {
            foreach (O4Cookie cookie in cookies)
            {
                if (cookie.Name.ToUpper().Equals(strField.ToUpper()))
                {
                    Value = cookie.Value;
                    fRtn = true;
                    break;
                }
            }
        }
     }
    catch (Exception)
    {
        Value = string.Empty;
        fRtn = false;
    }
    return fRtn;
}

In Closing

It is somewhat beyond the scope of this article to go into detail on parsing the Opera cookie file. However, the class is sufficiently commented and ready to use for reading cookies from Opera. Writing them is not supported in this C# class, but it is supported in the original Delphi solution on Experts Exchange [^].

So you're not a subscriber to EE? Don't let that get you down, try accessing via Google [^].

The chief difference between the Delphi solution and this C# class is how the cookie file is read. The Delphi solution reads from the file stream continually during the parsing process, while the C# class initially reads the file bytes into a buffer and then parses the buffered bytes after the read is completed.

History

  • Feb 13, 2012 version 1.0.0.0

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionNot working for Chrome and IE Pin
Rafsun8216-Dec-16 4:49
Rafsun8216-Dec-16 4:49 
AnswerRe: Not working for Chrome and IE Pin
David MacDermot16-Dec-16 10:15
David MacDermot16-Dec-16 10:15 
GeneralRe: Not working for Chrome and IE Pin
Rafsun8231-Dec-16 19:59
Rafsun8231-Dec-16 19:59 
QuestionInternetGetCookieEx Pin
sclavel18-Sep-15 1:07
sclavel18-Sep-15 1:07 
QuestionCookies Reading Pin
vishvadeepak8-Oct-14 21:21
vishvadeepak8-Oct-14 21:21 
AnswerRe: Cookies Reading Pin
David MacDermot9-Oct-14 6:31
David MacDermot9-Oct-14 6:31 
QuestionWon't work Pin
bert891727-Mar-14 8:17
bert891727-Mar-14 8:17 
AnswerRe: Won't work Pin
David MacDermot27-Mar-14 13:05
David MacDermot27-Mar-14 13:05 
GeneralRe: Won't work Pin
bert891711-Oct-14 4:39
bert891711-Oct-14 4:39 
GeneralRe: Won't work Pin
David MacDermot11-Oct-14 7:22
David MacDermot11-Oct-14 7:22 
GeneralRe: Won't work Pin
bert891712-Oct-14 8:58
bert891712-Oct-14 8:58 
QuestionEncrypted Pin
Member 106357541-Mar-14 9:30
Member 106357541-Mar-14 9:30 
AnswerRe: Encrypted Pin
David MacDermot6-Mar-14 9:45
David MacDermot6-Mar-14 9:45 
AnswerRe: Encrypted Pin
bert891713-Oct-14 4:20
bert891713-Oct-14 4:20 
GeneralRe: Encrypted Pin
David MacDermot13-Oct-14 6:44
David MacDermot13-Oct-14 6:44 
GeneralRe: Encrypted Pin
bert891714-Oct-14 10:48
bert891714-Oct-14 10:48 
AnswerRe: Encrypted (solution for Chrome) Pin
Chris00320-Jul-15 5:18
Chris00320-Jul-15 5:18 
Questionhow can i get the expires by the way Pin
Member 770078413-Dec-12 14:19
Member 770078413-Dec-12 14:19 
Questioncntid Pin
avi0xx12-Nov-12 3:01
avi0xx12-Nov-12 3:01 
AnswerRe: cntid Pin
David MacDermot12-Nov-12 5:30
David MacDermot12-Nov-12 5:30 
Questioncan i read IE, FF and chrome's cookie using C++ ? Pin
infant_coder20-Feb-12 21:58
infant_coder20-Feb-12 21:58 
AnswerRe: can i read IE, FF and chrome's cookie using C++ ? Pin
David MacDermot21-Feb-12 5:30
David MacDermot21-Feb-12 5:30 
Questiongood Pin
Ramesh_495914-Feb-12 17:15
Ramesh_495914-Feb-12 17:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.