跳过正文

我的 Firefox 自定义手记 - 隐私加固篇[1]

·5103 字·11 分钟
Firefox User.js 浏览器指纹 追踪 隐私
沉渊覆雪
作者
沉渊覆雪
故事的结局早已定下,但途中的故事还未曾书写

提示
#

本文部分(可能是大部分)配置都可能会牺牲性能, arkenfox不同于其他模板, 它侧重的是安全和隐私加固,性能优先级是低的

前言
#

作为一个可能是隐私偏执狂的人, 咱觉得要经常打交道的浏览器必须要可靠, 不能偷偷泄露我的隐私,同时也希望它可以抵御互联网上的各种追踪
显然, Chromium/Google Chrome 并不是个好选择(咕噜咕噜总是不作恶), Microsoft Edge, 大有继承 IE 大统的可能
而且没有uBlock Origin我活不下去

那么剩余的有 Brave 和 Mozilla Firefox, Brave 的默认抗追踪很不错, 笔者也会用它来放视频, 但是它的理念和可玩性使我更多把它作为不得不用Chromium系浏览器时候的选择
因此, 就开始对 Mozilla Firefox 动手动脚一下吧~~

Firefox 在现在, 默认情况下的保护并不会比 Brave 好, 甚至更差, Mozilla 现在似乎很是拮据, 要进军广告业务的样子, 修改用户条款, 隐私利好的广告服务, 不侵害隐私的归因(Privacy-Preserving Attribution:PPA)…我们改天分析下Mozilla的财报吧(挖坑ing…)
Mozilla 在远离它自己的保护隐私的宣传

所以, 闲话少说, 我们自己动手把Firefox变成我们的形状吧~~
我选择 Firefox ESR 作为日用版本, 因为它的更新周期更长, 没有功能更新, 更加稳定, Mozilla 要是做恶了也可以有更长时间反应
可能是我太保守, 不需要功能更新
此时 Firefox ESR 为 128 版本

user.js
#

简介
#

Firefox 的 about:config 是个神奇的地方, 你在这里修改许多高级设置项目, 包括那些可以防备网页追踪, Mozilla 遥测的部分
配置项保存在 Firefox 用户文件目录(可以打开about:profiles查看路径)下的 prefs.js 内 不过你会发现可配置项目太多了, 而且在浏览器里面配置似乎不太方便的样子

那么, 是时候为你介绍 arfenfox/user.js(原 ghacks-user.js) 了, 这是一个关于 Firefox 的隐私, 安全和追踪的 user.js 模板

为什么是 user.js 模板而不是 prefs.js 模板?
#

需要说明的是, 默认情况下配置是没有这个文件的, 记得手动创建此文本文件
一般来说, 建议通过 user.js 配置而不是用 prefs.js 当我们在 about:config 修改了配置项时, Firefox 会变更 prefs.js 的内容,而不会去变动 user.js ,重启后 Firefox 依然会以 user.js 的值为准
(user.js 的优先级高过 prefs.js)

示例
#

user_pref("browser.tabs.closeWindowWithLastTab", false);
// 这是一个配置项, 设置 Firefox 关闭最后一个标签页后是否退出, false 即不退出

user.js 中, 我们可以用 // 注释内容行/* 注释块内容 */ 来注释, 以上为示例

arkenfox/user.js 的使用
#

详情参考 https://github.com/arkenfox/user.js/wiki
当你从项目下载后
(我是Firefox ESR 128, 下载的是https://github.com/arkenfox/user.js/archive/refs/tags/128.0.zip)
注意, 对于 ESR 用户, 项目的 update.bat/update.sh 最好不使用的, 参见https://github.com/arkenfox/user.js/wiki/3.4-Apply-&-Update-&-Maintain#-esr-users

我们应该先运行 prefsCleaner.sh/ prefsCleaner.bat 脚本, 这会备份原来的 prefs.js ,然后新建一个都是默认项的 prefs.js
假如你不需要记录浏览器历史和更多跟踪保护, 这一步后就可以启动 Firefox 了
那接下来, 我们需要新建以一个 user-overrides.js 文件, 它的格式和 user.js 相同, 对于 release 通道(稳定版) Firefox 用户, 运行 arkenfox/user.js 的 update.sh/update.bat 来更新 user.js 时, 脚本会合并 user-overrides.js 内你的配置, 你不需要修改 user.js , 应该修改 user-overrides.js 来覆盖 user.js 的配置
⚠️对于 ESR 用户, 运行脚本时添加 -esr 参数也会这么做, 但是可能有未知兼容性问题, 不建议
建议 ESR 用户手动下载对应版本, 然后附加想要的配置项到 user.js 的末尾
(在 user.js 内部, 如果一个配置项配置两次, 会使用第二次赋的值, 即下一行的优先级高于上一行(重复行))

我的 user-overrides.js 配置
#

未给出的加固配置项一般已经包含在 arkenfox/user.js 内

一些日常使用你应该需要的
#

// 禁用退出时自动删除浏览历史记录
user_pref("privacy.clearOnShutdown_v2.historyFormDataAndDownloads", false);
// 禁用退出时自动删除浏览器 Cookies (删除了网站登录状态会清空, 不过我选择删除)
user_pref("privacy.clearOnShutdown_v2.cookiesAndStorage", false);

可能破坏网页, 但是抗追踪, 安全性加固
#

酌情设置

/* 控制何时发送跨域请求
 * 0=始终(默认),1=仅当基本域名匹配时,2=仅当网站主机匹配时
 * [注意]将导致网站损坏:较旧某些网站,例如银行 */
user_pref("network.http.referer.XOriginPolicy", 2);

// 禁用 WebRTC(可选,现在WebRTC通信已经受保护了)
// user_pref("media.peerconnection.enabled", false);
// 保护 WebRTC 通信时候你的私人IP, 但是通常会导致视频会议平台上的破坏
// user_pref("media.peerconnection.ice.no_host", true);

// 禁用"超链接审核"(单击跟踪)
user_pref("browser.send_pings", false);

// 是否启用 CSS 来区分已访问和未访问的链接(可能被网站用于获取你的浏览历史, 不过缓解措施已经实施, 可选)
// user_pref("layout.css.visited_links_enabled", false);

// 禁用Google提供的Widevine Content Decryption模块
user_pref("media.gmp-widevinecdm.enabled", false);

// 禁用所有DRM内容(EME:加密媒体扩展)
user_pref("media.eme.enabled", false);

// 禁用 Wasm (含有漏洞 - 被攻击的可能性)
user_pref("javascript.options.wasm", false);

// 防止网站所有者可以跟踪设备的电池状态
user_pref("dom.battery.enabled", false);

// 避免在网页复制, 选择, 粘贴或剪切某些内容时,网站可以知晓
user_pref("dom.event.clipboardevents.enabled", false);

// 禁用关键词搜索,避免意外向搜索引擎泄露信息
user_pref("keyword.enabled", false);

// 用于默认搜索引擎的位置信息
user_pref("browser.search.geoip.url", "");

// OpenH264 编解码器
user_pref("media.gmp-gmpopenh264.enabled", false);

// 禁止网站控制浏览器右键菜单 ( Shift + 右键可解 )
// user_pref("dom.event.contextmenu.enabled", false);

// 总是请求英文版网页,减少语言指纹
user_pref("privacy.spoof_english", 2);
// 设置语言偏好为英文(冗余)(测试发现,不使用privacy.spoof_english,只设置偏好还是会泄露浏览器UI语言)
user_pref("intl.accept_languages", "en-US, en");

// RFP(网页损坏高手,但是指纹保护很强)
user_pref("privacy.resistFingerprinting", true);
user_pref("privacy.resistFingerprinting.pbmode", true);
// 使窗口比例常见
user_pref("privacy.resistFingerprinting.letterboxing", true);

// 禁用webgl(大大降低了浏览器指纹,但是网页可能也要损坏了)
user_pref("webgl.disabled", true);
// 禁用地理位置功能
// user_pref("geo.enabled", false);
// 控制是否启用全屏API(Fullscreen API)
// 这个API允许网页将浏览器窗口切换到全屏模式
// user_pref("full-screen-api.enabled", false);
// (这些可能容易增加指纹熵(?))

// 第一方隔离(FPI),默认的dFPI(动态分区)更灵活,酌情开启
// user_pref("privacy.firstparty.isolate, true);
// 禁止信任系统安装的第三方证书(Linux无需)
user_pref("security.enterprise_roots.enabled", false);

对浏览器内部遥测的禁止
#

// 网站“push”需要订阅, 并且CRLITE需要API
// 删除所有订阅, 请重置"dom.push.useragentid"
// user_pref("dom.push.enabled", false);
user_pref("dom.push.useragentid", "");
// “安全浏览”提供网络钓鱼保护和恶意软件检查功能, 但可能会将用户信息(例如 URL、文件哈希等)发送给 Google 等第三方。
// 禁用下载检查功能
user_pref("browser.safebrowsing.malware.enabled", false);
user_pref("browser.safebrowsing.phishing.enabled", false);
user_pref("browser.safebrowsing.downloads.enabled", false);
// 禁用新的实验
user_pref("messaging-system.rsexperimentloader.enabled", false);
/* user.js 已有
// 禁用新的实验
user_pref("app.shield.optoutstudies.enabled", false);
// 禁用研究以及和 Normandy 相关的紧急修复及新功能推出
user_pref("app.normandy.enabled", false);
*/
// 更新附加组件元数据
user_pref("extensions.getAddons.cache.enabled", false);

功能上的小技巧?(疑)
#

// 开启 CSS 定制 UI
user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", "true");
// 使扩展可在 Mozilla 的网站运行
// 解除对某些 Mozilla 域(您还需要4503)的Webextension限制[FF60+]
user_pref("extensions.webextensions.restrictedDomains", "");
/* 禁用MozaddonManager Web API [FF57+]
[注意]要允许扩展在 AMO (Mozilla 扩展中心)上工作,您也需要2662 */
user_pref("privacy.resistFingerprinting.block_mozAddonManager", true);

字体指纹
#

目前似乎没有什么较好的办法去随机化字体(部分扩展看起来可以)
(browser.display.use_document_fonts 设为 0 只会让 Firefox 拒绝载入/渲染页面里通过 @font-face 之类方式声明的 Web 字体. 强制用本地默认字体来回退, 并不能阻止字体指纹收集)
我选择…从TorBrowser那提取字体, 把字体都安装进系统,然后…设置以下(我不好说这样的行为如何,但是如果这样做的人很多或许是个好办法不过显然我是少数和TorBrowser用户的字体指纹坐一桌, 但是我其他方面很突出)

user_pref("font.system.whitelist", "Arimo, Cousine, Noto Naskh Arabic, Noto Sans Adlam, Noto Sans Armenian, Noto Sans Balinese, Noto Sans Bamum, Noto Sans Bassa Vah, Noto Sans Batak, Noto Sans Bengali, Noto Sans Buginese, Noto Sans Buhid, Noto Sans Canadian Aboriginal, Noto Sans Chakma, Noto Sans Cham, Noto Sans Cherokee, Noto Sans Coptic, Noto Sans Deseret, Noto Sans Devanagari, Noto Sans Elbasan, Noto Sans Ethiopic, Noto Sans Georgian, Noto Sans Grantha, Noto Sans Gujarati, Noto Sans Gunjala Gondi, Noto Sans Gurmukhi, Noto Sans Hanifi Rohingya, Noto Sans Hanunoo, Noto Sans Hebrew, Noto Sans JP, Noto Sans Javanese, Noto Sans KR, Noto Sans Kannada, Noto Sans Kayah Li, Noto Sans Khmer, Noto Sans Khojki, Noto Sans Khudawadi, Noto Sans Lao, Noto Sans Lepcha, Noto Sans Limbu, Noto Sans Lisu, Noto Sans Mahajani, Noto Sans Malayalam, Noto Sans Mandaic, Noto Sans Masaram Gondi, Noto Sans Medefaidrin, Noto Sans Meetei Mayek, Noto Sans Mende Kikakui, Noto Sans Miao, Noto Sans Modi, Noto Sans Mongolian, Noto Sans Mro, Noto Sans Multani, Noto Sans NKo, Noto Sans New Tai Lue, Noto Sans Newa, Noto Sans Ol Chiki, Noto Sans Oriya, Noto Sans Osage, Noto Sans Osmanya, Noto Sans Pahawh Hmong, Noto Sans Pau Cin Hau, Noto Sans Rejang, Noto Sans Runic, Noto Sans SC, Noto Sans Samaritan, Noto Sans Saurashtra, Noto Sans Sharada, Noto Sans Shavian, Noto Sans Sinhala, Noto Sans Sora Sompeng, Noto Sans Soyombo, Noto Sans Sundanese, Noto Sans Syloti Nagri, Noto Sans Symbols, Noto Sans Symbols 2, Noto Sans Syriac, Noto Sans TC, Noto Sans Tagalog, Noto Sans Tagbanwa, Noto Sans Tai Le, Noto Sans Tai Tham, Noto Sans Tai Viet, Noto Sans Takri, Noto Sans Tamil, Noto Sans Telugu, Noto Sans Thaana, Noto Sans Thai, Noto Sans Tifinagh, Noto Sans Tifinagh APT, Noto Sans Tifinagh Adrar, Noto Sans Tifinagh Agraw Imazighen, Noto Sans Tifinagh Ahaggar, Noto Sans Tifinagh Air, Noto Sans Tifinagh Azawagh, Noto Sans Tifinagh Ghat, Noto Sans Tifinagh Hawad, Noto Sans Tifinagh Rhissa Ixa, Noto Sans Tifinagh SIL, Noto Sans Tifinagh Tawellemmet, Noto Sans Tirhuta, Noto Sans Vai, Noto Sans Wancho, Noto Sans Warang Citi, Noto Sans Yi, Noto Sans Zanabazar Square, Noto Serif Armenian, Noto Serif Balinese, Noto Serif Bengali, Noto Serif Devanagari, Noto Serif Dogra, Noto Serif Ethiopic, Noto Serif Georgian, Noto Serif Grantha, Noto Serif Gujarati, Noto Serif Gurmukhi, Noto Serif Hebrew, Noto Serif Kannada, Noto Serif Khmer, Noto Serif Khojki, Noto Serif Lao, Noto Serif Malayalam, Noto Serif Myanmar, Noto Serif NP Hmong, Noto Serif Sinhala, Noto Serif Tamil, Noto Serif Telugu, Noto Serif Thai, Noto Serif Tibetan, Noto Serif Yezidi, Pyidaungsu, STIX Two Math, Tinos, Twemoji Mozilla");

⚠在 Firefox 140 ESR 中, 此方法将失效
见:Consider deprecating font whitelist
Firefox 140 ESR 怎么搞先🕊了(我又在挖坑了)

以上参考了
https://arkenfox.github.io/gui/
https://wiki.mozilla.org/Privacy/Privacy_Task_Force/firefox_about_config_privacy_tweeks(可能过时)
非常建议去看看

一些误区
#

LibreWolf 和 arkenfox/user.js 的关系(?)
#

LibreWolf 是一个 Firefox 的社区衍生版, 预配置了 arkenfox/user.js ,删除了 Firefox 内的专有代码, 不过它是基于稳定版而不是ESR(延长支持版), 同时, 100%去除了遥测, ( Firefox 锁死了服务器URL, 仅仅修改 user.js 无法禁止它连接firefox.settings.services.mozilla.com,参考https://bugzilla.mozilla.org/show_bug.cgi?id=1598562)
(如何在 Firefox 内禁止它我们下次再说(先🕊了))

随机化指纹?
#

客观上说, arkenfox-user.js/LibreWolf 都不是做 “随机化指纹”
常有人以随机化指纹宣传它们是"片面的/误解的", arkenfox-user.js/LibreWolf 确实做了 “随机化”, 比如 Canvas 的随机, 但是并不意味者指纹是随机的, 随机化的值实际上也可以被检测到
比如 EFF 的测试知道你在随机化, 有人的指纹会和你相同, Amiunique 则相信你的随机化的那部分数据, 所以你在 Amiunique 的测试中总是独一无二的(但是你的指纹实际上不是随机的, 这是测试的问题)

可能他们是把 Canvas 随机化 = 指纹随机化了…(某种意义上讲确实对"初级"脚本(见下文)随机了……)

建议阅读:
If you don’t use RFP, then you’re on your own. And don’t rely on entropy figures from test sites.
https://github.com/arkenfox/user.js/issues/1228
https://github.com/arkenfox/user.js/issues/1821


3.3 Overrides [To RFP or Not]:

指纹保护的两个准则:
1:保护每个度量指标的真实值——具体如何实现并不重要。
2:保护足够多的度量

实际上 Arkenfox 并没有保护足够多的

"初级"脚本(NAIVE)
如果脚本只能"吞掉"随机化后的值,就称为"初级"脚本。
随机化度量越多,脚本变成初级的可能性越大。
欺骗初级脚本不需要“人群”。

"高级"脚本(ADVANCED)
所有随机化都可以被检测到——这是事实。能检测到这一点的脚本就是“高级”脚本。
高级脚本也有不同层次的复杂度。
要对抗高级脚本,需要“人群”,人群越大越有效。
可选地对部分度量进行随机化,以应对初级脚本

Arkenfox 的主要目标一直是: 安全, 隐私, 以及减轻诸如"状态追踪"和"导航追踪"这类真实且大规模的跟踪威胁
但是也会对“无状态追踪”有所抵御
Arkenfox 从未声称能够对抗高级指纹识别


RFP 的多数指标硬编码的固定化(除了Canvas), 实在不能说是指纹随机化

可以尝试打开 https://abrahamjuliot.github.io/creepjs/
来看看指纹是否真的随机了

所以, 我想说的是, 它可以使得许多用户画像追踪方法失效
据说可以应对99%的情况(arkenfox/user.js 项目开发者的玩笑啦)(总之是足够日常的保护)
但是对于creepjs这类"高级"检测, 我们应该选择去隐匿于人群中–>指纹统一化

对于大部分人来说, 日常使用这样配置已经绰绰有余啦~~
不过假如你的威胁模型需要非常完备的保护(斯诺登那种级别的(疑?)), 这不是个很好的, 值得满意的方案
浏览器指纹测试(仅供参考)(也可以拿其他浏览器测测对比下)

https://arkenfox.github.io/TZP/tzp.html
https://abrahamjuliot.github.io/creepjs

UTC 还是 Atlantic/Reykjavik?
#

曾经时区确实设置为 “UTC”, 不过现在并不是了
RFP设置的时区不再是 UTC, 而是 Atlantic/Reykjavik(冰岛,时区偏移量也为0), UTC 是 FF55+ 的行为
参考
https://github.com/arkenfox/user.js/issues/1846#issuecomment-2183064738

扩展推荐
#

提供更加强大的canvas指纹保护(不过可能损坏网页)(有FPP在,你不大需要)
https://addons.mozilla.org/firefox/addon/canvasblocker/

临时容器扩展(可选)(不建议) 效果约等于FPI(第一方隔离),不过更加灵活,但是不会再有维护了(开发者不幸离世了),
https://github.com/stoically/temporary-containers/issues/618
非常感谢你, @stoically

不大活跃的社区fork:https://addons.mozilla.org/firefox/addon/temporary-containers-plus/
uBlock Origin
https://raw.githubusercontent.com/DandelionSprout/adfilt/master/LegitimateURLShortener.txt
(ClearURL上位替代规则) 参考:https://github.com/arkenfox/user.js/wiki/4.1-Extensions (不过我其实也在用NoScript的说)

推荐文章
#

https://gitlab.torproject.org/tpo/applications/wiki/-/wikis/Design-Documents/Tor-Browser-Design-Doc

If you do nothing on desktop, you are already uniquely identifiable - screen, window and font metrics alone are probably enough - add timezone name, preferred languages, and several dozen other metrics and it is game over. Here is a link to the results of a study done in 2016 showing a 99.24% unique hit rate (and that is excluding IP addresses).
如果您在桌面上什么都不做,那么您已经可以唯一地识别了 - 屏幕,窗口和字体指标可能就足够了 - 添加时区名称,首选语言以及其他数十个指标,并且已经结束了。 这是与2016年进行的研究结果的链接,显示了99.24%的唯一命中率(这不包括IP地址)。
https://www.ndss-symposium.org/ndss2017/ndss-2017-programme/cross-browser-fingerprinting-os-and-hardware-level-features/