没有 cookie 的网站的解决方法?

信息安全 隐私 饼干 追踪
2021-09-02 16:07:50

为了防止跟踪的隐私,我将浏览器设置为默认拒绝 cookie。我只允许来自白名单域的 cookie。一般来说,这对我来说没问题。但是,我现在至少有一个案例变得不方便。我支付了华盛顿邮报的数字订阅费,因为我喜欢他们的新闻并希望支持它,但我不希望他们或他们的广告商跟踪我,所以我从不登录,也不接受他们的 cookie。直到最近,这一直很好。在过去的几天里,他们在他们的网站上做了一些新的事情,结果虽然我可以查看他们的主页,但如果我点击一个故事,我会在 Firefox 中收到以下消息:

页面未正确重定向。Firefox 检测到服务器正在以永远不会完成的方式重定向对该地址的请求。此问题有时可能是由禁用或拒绝接受 cookie 引起的。

这不是他们为网站付费。在设置为接受所有 cookie 的浏览器中,我无需登录即可访问他们的所有内容,但任何页面点击都会创建大约 20 个来自washtonpost.com 的 cookie 和大约 20 个来自其广告商的 cookie。如果我转到主页,清除 cookie,然后单击故事的链接,它可以工作,但 cookie 会重新创建。因此,我尝试查看的页面上似乎有代码尝试创建这些 cookie,然后如果创建 cookie 失败则抛出错误。

对于这种情况,有什么好的策略可以保护我的隐私吗?例如,我考虑编写一个脚本,该脚本将在我的机器上每 10 秒运行一次,并删除除白名单域之外的所有 cookie。

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

3个回答

如果您担心跟踪器,您可能正在寻找First Party Isolation

First Party Isolation 是 Firefox 从 Tor 浏览器的Cross-Origin Identifier Unlinkability概念中采用的一项功能。FPI 的工作原理是将所有 cookie 链接到第一方域(URL 栏中的那个),从而使不同域之间的第三方 cookie 区分开来。也就是说,如果您正在访问a.com并且跟踪器设置了一个 cookie,并且稍后访问b.com使用相同的跟踪器,那么当第一方域不同时,它将无法看到它之前放置的 cookie ( a.com)。另一种解释:

什么是第一方隔离

FPI 通过在每个域的基础上分离 cookie 来工作。这一点很重要,因为大多数在线广告商会在用户计算机上为用户访问的每个站点放置一个 cookie,并且广告商会加载广告。

启用 FPI 后,广告跟踪器将无法看到它放置在该用户 PC 上的所有 cookie,而只能看到为用户当前正在查看的域创建的 cookie。

这将迫使广告跟踪器为用户访问的每个站点创建一个新的用户配置文件,并且广告商将无法将这些 cookie 和用户的浏览历史汇总到一个庞大的配置文件中。

(来源)

要启用FPI ,您可以转到about:config并设置privacy.firstparty.isolatetrue,或安装现在非官方的第一方隔离插件但在您激活它之前,请注意某些网络应用程序依赖第三方 cookie 来实现实际功能,并且之后可能会变得无法使用(例如,您可能无法登录)。如果您遇到此类问题,请尝试将隔离规则设置privacy.firstparty.isolate.restrict_opener_accessfalse哪个,这样您就不太可能在跨域登录流程(例如在不同域之间重定向您)期间遇到问题。


Firefox 中的另一种方法是容器

使用容器,您基本上可以将不同的会话彼此隔离,而不必使用多个浏览器配置文件。例如,您可以在不同的容器中读取 WaPo,并且该容器中的跟踪器设置的任何 cookie 在其他容器中不可见。容器在 Firefox Nightly 中和作为附加组件可用。

(Chrome 没有这个确切的功能,但您可以使用多个配置文件来获得相同的效果。)


我考虑编写一个脚本,该脚本将在我的机器上每 10 秒运行一次,并删除除白名单域之外的所有 cookie。

我看到的问题是某些站点在您删除它们后立即重新创建 cookie(只要您仍然加载它们的脚本)。如果你的时机不好,你最终可能会遇到与禁用 cookie 相同的问题。

最后,还有一些著名的插件,例如Ghostery,可以检测和阻止已知的跟踪器。因此,您有很多选项可以在不完全禁用 cookie 的情况下维护您的隐私——不幸的是,这并不能让您在现代网络中走得很远。

启动一个隐身浏览器窗口(或虚拟机实例,如果你真的偏执的话)来查看 WaPo,然后只将它用于该站点,或者每次访问时关闭它并打开一个新站点。

这只是我自己问题的一个可能答案,可能不是最佳答案,但我认为值得描述。我尝试了使用脚本删除不在白名单上的 cookie 的想法。下面是我想出的用于 Firefox 的 ruby​​ 脚本。我在 linux 中对其进行了测试,但它可能可以跨平台使用(可能需要为 Windows 更改文件路径中的斜线?)。

看来,虽然我可以立即从存储它们的 sqlite 文件中删除 cookie,但 firefox 使用它自己的 cookie 内存副本。因此,在我重新启动 Firefox 之前,cookie 的删除实际上不会生效。

Firefox 实际上有自己的机制,可以在每个会话结束时删除除白名单外的所有 cookie。但是,您必须选择使用该机制或在会话中对 cookie 使用白名单。通过执行后者并使用此脚本,我获得了更精细的控制:我有不允许设置 cookie 的站点(默认)、列入灰名单的站点(会话结束后清除 cookie),以及列入白名单的网站。

优点:

  • cookie 实际上已经消失(在重新启动后),而不是像 FPI 中那样被隔离。这使得很容易知道发生了什么。
  • 像washingtonpost.com 这样的网站运行绝对正常,因为我还在网站上时不会删除cookies。
  • 跨平台(-ish?)。
  • 维护白名单对我来说很简单。

缺点:

  • 这只会阻止跨会话扩展的跟踪。它不会阻止会话中的短期跟踪。
  • 仅适用于火狐。

代码:

#!/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()