20

For privacy against tracking, I have my browser set up to refuse cookies by default. I only allow cookies from whitelisted domains. In general, this works OK for me. However, I now have at least one case where it has become inconvenient. I pay for a digital subscription to the Washington Post, because I like their journalism and want to support it, but I do not want them or their advertisers tracking me, so I never log in and don't accept cookies from them. This has worked fine until recently. Within the last few days, they have done something new on their web site with the result that although I can view their home page, if I click through to a story, I get this message in firefox:

The page isn’t redirecting properly. Firefox has detected that the server is redirecting the request for this address in a way that will never complete. This problem can sometimes be caused by disabling or refusing to accept cookies.

This is not them paywalling the site. In a browser set up to accept all cookies, I can access all their content without logging in, but any page click creates about 20 cookies from washingtonpost.com and about 20 cookies from their advertisers. If I go to the home page, clear the cookies, and then click on a link to a story, it works, but the cookies get recreated. So it appears that there is code on the pages I'm trying to view that attempts to create these cookies and then throws an error if creating the cookies fails.

Is there any good strategy for this type of situation that preserves my privacy? For example, I thought about writing a script that would run every 10 seconds on my machine and delete all cookies except those from whitelisted domains.

related: https://askubuntu.com/questions/368325/how-to-clear-browsers-cache-and-cookies-from-terminal

  • 1
    Have you tried disabling third-party-cookies only (but accepting the sites own cookies) for this particular domain? – Bergi Feb 15 '18 at 04:56
  • @Bergi: Yes, I tried that, but it actually didn't seem t block the cookies. –  Feb 15 '18 at 16:19
  • An additional technique that helps here is to block javascript on the site in question (e.g., washingtonpost.com). I'm currently doing this using yesscript2 in firefox, and it prevents the WaPo page's javascript from running and covering up the story because it detects that its advertisers' tracking has failed. –  May 18 '18 at 21:12

3 Answers3

31

If you're concerned about trackers, you're probably looking for First Party Isolation.

First Party Isolation is a feature that Firefox adopted from the Tor browser's Cross-Origin Identifier Unlinkability concept. FPI works by linking all cookies to the first-party domain (the one in the URL bar), making third-party cookies distinct between different domains. That is, if you're visiting a.com and a tracker sets a cookie, and later visit b.com which uses the same tracker, it won't be able to see the cookies it has placed earlier, when the first-party domain was different (a.com). Another explanation:

What is First-Party Isolation

FPI works by separating cookies on a per-domain basis. This is important because most online advertisers drop a cookie on the user's computer for each site the user visits and the advertisers loads an ad.

With FPI enabled, the ad tracker won't be able to see all the cookies it dropped on that user's PC, but only the cookie created for the domain the user is currently viewing.

This will force the ad tracker to create a new user profile for each site the user visits and the advertiser won't be able to aggregate these cookies and the user's browsing history into one big fat profile.

(Source)

To enable FPI, you can either go to about:config and set privacy.firstparty.isolate to true, or install the now unofficial First Party Isolation add-on. But before you activate it, be aware that some web apps rely on third-party cookies for actual functionality and may become unusable afterwards (e.g. you might be unable to log in). If you experience such problems, try also setting privacy.firstparty.isolate.restrict_opener_access to false which will relax the isolation rules and you're less likely to experience problems during, say, a cross-domain login flow that redirects you between different domains.


Another approach in Firefox are containers.

With containers you're essentially isolating different sessions from each other without having to use multiple browser profiles. E.g., you could read WaPo in a distinct container, and any cookies set by trackers in that container wouldn't be visible in the other ones. Containers are available in Firefox Nightly and as an add-on.

(Chrome doesn't have this exact feature, but you can use multiple profiles to get the same effect.)


I thought about writing a script that would run every 10 seconds on my machine and delete all cookies except those from whitelisted domains.

The problem I see with this is that some sites re-create cookies immediately after you delete them (as long as you still have their scripts loaded). And if your timing is bad, you might eventually run into the same problems you had with disabled cookies.

Finally, there are also reputable addons such as Ghostery that detect and block known trackers. So, you have plenty of options to maintain your privacy without disabling cookies entirely -- which unfortunately doesn't get you very far in the modern web.

Pablo A
  • 123
  • 5
Arminius
  • 43,922
  • 13
  • 140
  • 136
5

Fire up an incognito browser window (or VM instance if you are really paranoid) to view WaPo, then only use it for that site, or close it and open a new one each time you visit.

JesseM
  • 1,882
  • 9
  • 9
0

This is just one possible answer to my own question, and probably not the optimal one, but I thought it was worth describing. I tried out the idea of a script to delete cookies that aren't on a whitelist. Below is a ruby script for use with firefox that I came up with. I tested it in linux, but it's probably usable in a cross-platform way (maybe slashes in the file path need to be changed for Windows?).

It appears that although I can immediately delete the cookies from the sqlite file they're stored in, firefox uses its own in-memory copy of the cookies. Therefore the deletion of the cookies doesn't actually take effect until I restart firefox.

Firefox actually has its own mechanism for deleting all but whitelisted cookies at the end of each session. However, you have to choose either to use that mechanism or to use whitelisting for cookies within a session. By doing the latter and also using this script, I get more granular control: I have sites that aren't allowed to set cookies (the default), sites that are gray-listed (cookies cleared after the end of the session), and sites that are whitelisted.

Pros:

  • The cookies are actually gone (after a restart) rather than walled off as in FPI. This makes it easy to tell what is going on.
  • A site like washingtonpost.com functions absolutely normally, because the deletion of the cookies doesn't take place while I'm still on the site.
  • Cross-platform (-ish?).
  • It's straightforward for me to maintain a whitelist.

Cons:

  • This only prevents tracking that extends across sessions. It won't prevent short-lived tracking within a session.
  • Only works for firefox.

Code:

#!/usr/bin/ruby

require 'sqlite3'

# Delete all cookies except those from hosts on the following list.
# Note that firefox keeps its cookies cached in memory, so this cleaning will not
# take effect inside firefox until you restart firefox.

# Putting foo.com on this list automatically includes www.foo and .foo.
$allowed_hosts = [
  "amazon.com",
  "bit.ly",
  "github.com",
  "gmx.com",
  "rockclimbing.com",
  "stackexchange.com"
]

$allowed_hosts_all_forms = []
$allowed_hosts.each { |host|
  $allowed_hosts_all_forms.push(host)
  $allowed_hosts_all_forms.push("www."+host)
  $allowed_hosts_all_forms.push("."+host)
}

def main
  # https://unix.stackexchange.com/questions/82597/where-does-firefox-store-its-cookies-on-linux
  # loop over profiles
  Dir.glob( "#{Dir.home}/.mozilla/firefox/*.default/cookies.sqlite").each { |cookie_file_name|
    print "cookie file #{cookie_file_name}\n"
    begin
      db = SQLite3::Database.open(cookie_file_name)
      print "before deletion:#{list_all_hosts(db).sort.join(' ')}\n"
      allowed = []
      $allowed_hosts_all_forms.each {|host| allowed.push("'#{host}'") } # surround with single quotes
      #print "delete from moz_cookies where host not in (#{allowed.join(',')});"
      db.execute("delete from moz_cookies where host not in (#{allowed.join(',')});")
      print "after deletion:#{list_all_hosts(db).sort.join(' ')}\n"
    rescue SQLite3::Exception => e 
      puts "Exception occurred"
      puts e
    ensure
      db.close if db
    end
  }
end

def list_all_hosts(db)
  hosts = []
  db.execute("SELECT host,name FROM moz_cookies").each { |row|
    hosts.push(row[0])
  }
  return hosts
end

main()