I try to keep my Firefox cookie file clean. I used to run a script on cookies.txt to remove most cookies and keep only the ones for sites I visit often and trust. This was simple when the cookie file format was plain text. However, Firefox has been moving files to the sqlite format, and my script no longer works.

Sqlite seems to be pretty nice. The first thing I needed to do was figure out what format cookies.sqlite used. I ran select * from sqlite_master using the command line interface and it told me there was a table named moz_cookies with (id INTEGER PRIMARY KEY, name TEXT, value TEXT, host TEXT, path TEXT,expiry INTEGER, lastAccessed INTEGER, isSecure INTEGER, isHttpOnly INTEGER) as columns. Pretty straightforward. I used this information, plus the Python sqlite3 module (standard with Python 2.5) to write a script to clean up my Firefox cookies:

#!/usr/bin/python
# Change this to where your cookies file is
COOKIE_FILE = ('/Users/amitp/Library/Application Support'
    '/Firefox/Profiles/foobar/cookies.sqlite')
HOSTS = [  # keep only cookies from these hosts
    u'.blogger.com',
    u'www.blogger.com',
    u'.delicious.com',
    u'.discus.com',
    u'discus.com',
    u'blobs.discus.com',
    u'.github.com',
    # … other hosts omitted in this example code
    ]

# Connect and then issue commands
# through the “cursor” object
import sqlite3
connection = sqlite3.connect(COOKIE_FILE)
cursor = connection.cursor()

# Remove Google Analytics cookies from all sites
cursor.execute('DELETE FROM moz_cookies WHERE name IN'
          ' ("__utma", "__utmb", "__utmc", "__utmz")')

# Remove any cookies from non-approved hosts
cursor.execute(
   'DELETE FROM moz_cookies WHERE host NOT IN (%s)'
    % (','.join(len(HOSTS) * ['?'])),
    HOSTS)

# Commit changes to disk,
# locking the file during the process
connection.commit()

# Print the cookies we have left
print 'After:'
rows = list(cursor.execute(
          'SELECT host, name FROM moz_cookies'))
for row in rows:
    print '%30s : %s' % row

The script opens the cookies.sqlite file (unlike cookies.txt, it appears to be safe to open and edit this file while Firefox is running!), removes most cookies, commits the changes, and prints out the remaining cookies.

Lots of the Firefox profile information has been moved into the sqlite format (instead of the mess we had before), so I should explore some of the other files to see what might be fun to play with.

Labels:

13 comments:

Hemebond wrote at Wednesday, June 10, 2009 at 12:59:00 AM PDT

Why not just tell Firefox to nuke any untrusted cookies when you close Firefox?

Amit wrote at Wednesday, June 10, 2009 at 8:47:00 AM PDT

Hemebond, the only options I found in Firefox were per-site, and it seemed to be to block cookies. I wanted to allow cookies from certain sites, and I also wanted to remove some of the cookies even on “trusted” sites. I got more control of this through a script. In the future I might build some histograms of which cookies are being issued, along with sizes and expiration dates.

Anonymous wrote at Saturday, June 27, 2009 at 7:06:00 AM PDT

Amit...understanding that you might want to keep some cookies can't I just delete the file and next time Fire fox opens it'll create a new [empty] file?

Amit wrote at Saturday, June 27, 2009 at 8:45:00 AM PDT

Yes, you can delete it if you don't want any cookies. Or you can block cookies from the Firefox settings. The SQL approach is handy when you want to apply more complex rules.

Anonymous wrote at Thursday, July 2, 2009 at 10:25:00 AM PDT

Hey Amit

in firefox 3.5 the database file seems to be locked while firefox is open so it can only be opened and edited when firefox is closed...

do you know if there's a way round that?

Amit wrote at Friday, July 3, 2009 at 8:04:00 AM PDT

Hi Anonymous, sorry, I don't know of a way around it. I just upgraded to 3.5 and can't run my script while Firefox is running. Fortunately I don't leave my browser running all the time so I will just have to run the script after I quit the app.

Anonymous wrote at Tuesday, August 11, 2009 at 10:18:00 AM PDT

hm maybe there's some FF addon which stops the database file from locking while firefox is running?

Dimon wrote at Wednesday, January 20, 2010 at 1:43:00 PM PST

Great stuff. But when firefox is running it locks database:
demon@comp:~$ python cookies.py
Traceback (most recent call last):
File "cookies.py", line 20, in
cursor.execute('DELETE FROM moz_cookies WHERE host IN (".kauno.diena.lt",".diena.lt")')
sqlite3.OperationalError: database is locked

Any ideas how to unlock database to manipulate its tables while firefox is running?

Bart N. wrote at Tuesday, February 21, 2012 at 5:08:00 AM PST

Excellent post, this was very helpful to me. I'm running a linux terminal services setup where I needed to script cookie removal for potentially running Firefoxes. It turns out that Firefox 10 at least does not lock its cookie database, so I could do it easily using your script. Thanks a lot!

Anonymous wrote at Sunday, March 11, 2012 at 10:07:00 AM PDT

I use the CookieCuller addon, which has been around since about 2004. It does the same thing by letting me protect specific cookies from deletion. Then I can let Firefox delete cookies, but those marked protected will be saved. All without having to install Python and run a script.

. wrote at Sunday, October 14, 2012 at 4:24:00 AM PDT

Relating to this Article there is another Blog Article, wich serves a little bash script providing searching and deleting of Firefox Cookies: http://blog.ueffing.net/Anzeigen-und-Loeschen-von-Firefox-Cookies-ueber-Konsole-mit-sqlite3/

Anonymous wrote at Friday, April 19, 2013 at 5:44:00 AM PDT

Your example was pretty much what I was looking for. Thank you!

Anonymous wrote at Saturday, September 28, 2013 at 12:09:00 PM PDT

Amit,

Very nice solution. Thanks.