max / 경량화 브라우저 지문 & 추적 방어 쉴드

Install steps: Install a userscript manager, select Install, then open a website matched by the script.

Userscript HOWTO за начинаещи Chrome Edge Firefox

Публикувано:

Версия: 1.8.1+0185d86

Резюме: 캔버스(measureText 포함)·WebGL·WebGPU·WebCodecs·오디오 읽기에 페이지를 열 때마다 새로 정하는 노이즈를 넣어, 그 값으로 만든 지문을 사이트끼리, 방문끼리 잇기 더 어렵게 합니다. IP·User-Agent·글꼴·화면·시간대·언어·GPU 이름·CPU 코어 수·메모리·배터리는 바꾸지 않습니다. 워커·오디오 워클릿처럼 닿지 않는 곳에서는 원래 값이 읽히고, 노이즈 자체도 드러날 수 있습니다. 브라우저 자체 지문 보호와 함께 쓰세요.

Лиценз: MIT; https://opensource.org/licenses/MIT

Лиценз: Copyright (c) 2026 LiteWeaver. All Rights Reserved.

Антифункция: неуточнено

Source and freshness

The following figures come from the original source and are separate from activity on this site.

Original script: 轻量级浏览器指纹 & 追踪防御盾

Source version: 1.7

Last source check:

Last successful check:

Source daily installs
0
Source total installs
0
OpenUserJS install requests
0

Requests received by this site are not proof that a user completed installation.

Clicking Install records a request on this site; it does not confirm installation. Not working after install? View troubleshooting and issues

🛡️ 清除 Cookie 也抹不掉的“浏览器指纹”,让它每次打开页面都不一样

即使清除了 Cookie、打开了无痕窗口,网站仍有办法认出你。画布(Canvas)上所绘图像的细微像素差异、音频处理的结果、GPU 名称、CPU 核心数等数值组合在一起,就构成了能识别你浏览器的“指纹”(fingerprint)。而且与 Cookie 不同,指纹无法删除。

本脚本会为从画布、WebGL、WebGPU、WebCodecs 和音频中读取的数值,以及画布文字尺寸(measureText),加入每次打开页面时重新选定、看不见也听不到的噪声。由这些值生成的指纹每次打开都会不同,因此无论在网站之间还是在各次访问之间,都很难把它们关联起来。像 GPU 名称、核心数这样在本脚本无法触及的地方(Worker、请求头等)也能读到的数值,本脚本特意不作修改。这是因为,如果只在窗口中修改,数值就会彼此矛盾,而这种矛盾反而会成为痕迹。

  • ⚡ 安装后刷新即可 —— 无需任何设置,在所有网站上立即生效。
  • 🎯 同一页面内始终如一 —— 在同一页面中,同一图像无论读取多少次都得到相同的值,因此也能通过“读取两次、不一致就丢弃”的稳定性检测。
  • 👀 画面和声音都保持原样 —— 像素颜色最多只变化 256 级中的 1 级,声音的变化也只有听不见的幅度(对 0 dBFS 以内的信号最多约 -123 dBFS)。
  • 🔒 不对外通信,也不存储 —— 脚本中没有自行连接服务器或发送数据的代码,噪声密钥也不会存储在任何地方。代码未经压缩,原样公开。

✨ 有何不同?

1. 每次打开页面都是新指纹,同一页面内数值不变

噪声由脚本启动时用 crypto.getRandomValues 新生成的 32 位密钥决定。同一页面内密钥不变,因此同一图像无论读取多少次、读取局部还是全部、用何种方式读取,得到的值都相同;而刷新、打开新标签页或再次访问时会使用新密钥,因此包含画布和音频数值的指纹哈希会随之改变。例如,FingerprintJS 5.2.0 开源版在 Chromium 内核浏览器上会把画布和音频数值也纳入访客哈希,因此该哈希应当也会在每次打开页面时改变(这是根据源代码得出的判断,并未与本脚本一起实际运行过)。

阻止读取的方式每次随机改变的方式本脚本
使用画布的网站容易出问题大多正常大多正常(吸管、拾取等小范围读取不加噪声)
再次读取同一图像同样的空白值数值不同,噪声立即暴露相同的值(同一页面内)
再次打开页面同样的空白值新的值新的值
不同网站之间同样的空白值(使用的人少时反而显眼)各不相同各不相同

※ 对于与预先已知数值的图像进行比对的检测(known-answer),三种方式都会暴露。请参阅下方的“注意事项”。

  • 为何既不存储也不固定密钥:在页面内运行的用户脚本没有页面读不到的存储空间(存在网站上的数据,该网站的所有脚本都能读取和修改),而固定的密钥在所有网站上都会是同一个值。1.8 版放弃 1.7 版按网站划分的密钥的原因,写在下方的“1.8 版更新内容”中。
  • iframe 与弹出窗口:本脚本从所在窗口安装钩子的同源 iframe 和弹出窗口,与该窗口使用同一个密钥;脚本管理器另行注入本脚本的跨源 iframe 则使用自己的密钥(以同源地址打开的弹出窗口等窗口,其自身的实例也会安装钩子;在这类窗口中,音频会再叠加一个密钥,因此数值不同)。
  • 代价:会记住设备的网站可能每次访问都把你当作新设备(见下方的“注意事项”)。

2. 换一种读取方式,噪声依然相同

不仅保护画布(2D 和 OffscreenCanvas),还保护 WebGL、WebGPU、WebCodecs(VideoFrame)、画布录制(captureStream)、文字尺寸(measureText)乃至音频。无论以 8 位还是浮点数读取、读取局部还是全部,也无论经由 getImageData、VideoFrame.copyTo 还是纹理读取,同一像素都会加入相同的噪声,因此靠改变读取方式进行比对,很难去除噪声。新创建的同源 iframe 也会得到同样的保护;在跨源 iframe 中,则由脚本管理器注入该文档的实例用自己的密钥加入噪声(若管理器不向 iframe 注入,则为原始值)。不过,在不透明源 iframe(sandbox、data:)以及 Worker 和音频 Worklet 中,读到的是原始值(1.8 版不包装 Worker 和 Worklet,原因见下方的“1.8 版更新内容”)。

3. 减少痕迹的隐蔽钩子

被修改的函数都是包装原函数的 Proxy,因此 toString()、name、length 以及 bind() 的结果都与原函数相同;经由钩子抛出的错误,其堆栈也会去掉本脚本的行,重建成原生函数本应产生的样子。本脚本不会在 window 上留下标记,还会隐藏 Tampermonkey、Violentmonkey 写入堆栈中脚本地址的安装 ID 等用户专属值。不过,在同时禁止 eval 和内联脚本的页面以及 Firefox 上无法隐藏,而且比本脚本先运行的页面代码能够获知这些值和设置(见下方的“已知局限”)。在无需保护的页面上,根本不会挂上钩子。但这并不能让脚本隐身,噪声本身就可能暴露它。

4. 不与浏览器的保护冲突

如果某个网站上 Brave Shields 的指纹保护正在生效,本脚本会自动关闭重叠的画布和音频噪声。如果浏览器或其他扩展已经在修改画布(例如 Firefox RFP),本脚本就会让步,关闭自己的画布噪声。这样可以避免因双重修改而导致数值不一致。指纹保护在浏览器于所有地方统一施加时效果最好,因此本脚本是作为辅助手段,为缺少这类保护的 Chromium 内核浏览器而做的。

5. 避免破坏网站

  • 吸管工具、图形选择(Konva、Fabric 等)、地图和 3D 查看器中的拾取等只读取鼠标下几个像素来选择对象的小范围读取(少于 256 像素且不超过画布的 1/4),在规定的预算内不加噪声。该预算由窗口和它安装钩子的同源 iframe 共享,因此把大图切成小块读取的攻击会被放慢到每秒只能读取预算范围内的像素。但这无法完全阻止攻击,而且脚本管理器另行注入本脚本的跨源 iframe 各有自己的预算。
  • 每帧都作为纹理上传或被录制的大画布(游戏、图表)为节省复制开销而保持原样。
  • 出现问题的网站只需一行设置即可设为例外。

6. 经过验证,不隐瞒局限

  • 1.8 版在使用 Playwright 和无头 Chromium 141 运行的 12 个测试文件中没有任何失败。其中,一致性测试(检查窗口、iframe、Worker 和请求头是否显示相同的数值,以及挂钩的成员是否与预定列表一致等)通过了 535 项,另有 16 项的表现与 README 中作为局限记载的行为完全一致(KNOWN)。在同样的测试中,1.7 版的这类项目有 72 项,这是因为 1.8 版删除的数值伪装在 1.7 版中仍然存在,其行为被记为 1.7 版特有的已知行为。
  • 未能在真正的 Tampermonkey、Firefox 和真正的 Brave 上测试(Violentmonkey 使用从源代码构建的 2.49.4 测试版进行了测试)。
  • 本脚本无法防范的主要情况,写在下方的“注意事项”和“已知局限”中。

🧩 保护哪些内容?

对象网站读取的数值本脚本的处理默认
画布绘制图像后读回的像素(toDataURL、toBlob、getImageData、convertToBlob)每个页面重新选定的噪声(颜色变化不超过 1 级)开启
WebGL、WebGPU用 readPixels、copyTextureToBuffer 读取的像素,把画布作为纹理上传后读回的值(约 360×360 以内的画布)同样的噪声开启
视频帧与录制VideoFrame.copyTo,由画布生成的 VideoFrame、ImageBitmap 以及 captureStream()(约 360×360 以内的画布)同样的噪声开启
文字尺寸画布 measureText 结果的小数部分移动不超过一格(1/65536 px;值在 256 px 及以上时为 float32 的最小单位)开启
音频OfflineAudioContext 的结果、AnalyserNode、DynamicsCompressorNode.reduction、ScriptProcessor 的输入听不见的噪声(每 8 个采样中有 1 个移动 ±1 ulp)开启
WebRTC页面提供的 STUN、TURN 服务器移除服务器设置(无法隐藏公网 IP)关闭

不作修改的数值:如果只在窗口中修改,就会与 Worker、请求头、CSS 等本脚本无法触及之处的数值相矛盾,而这种矛盾会成为新的痕迹。因此以下数值保持原样。

数值能读到同样数值的地方
CPU 核心数、内存所有 Worker、sandbox iframe,Device-Memory 请求头(网站请求时)
GPU 名称、WebGL 和 WebGPU 的上限与功能所有 Worker、sandbox iframe
User-Agent、Client Hints、语言所有地方以及请求头
时区所有地方(修改后屏幕上显示的时间会出错,也会与 IP 所在位置不符)
电池本脚本无法触及的 sandbox iframe
屏幕和窗口尺寸CSS 媒体查询
字体、通过 DOM 测得的文字宽度布局 API,CSS 和 FontFace 的 local()

🙋 推荐给这些人

  • 清除了 Cookie、用了无痕窗口,网站却仍能认出自己,对此感到不安的人
  • 想继续照常使用没有自带指纹保护的 Chrome、Edge,又希望自己的访问更难通过画布和音频指纹被关联起来的人
  • 希望能通过代码亲自确认工具改了什么、怎么改的人
  • 对指纹采集技术和防护原理感兴趣的开发者

📦 安装

  1. 在浏览器中安装 Tampermonkey(篡改猴)或 Violentmonkey(暴力猴)。
  2. 点击本页面的安装按钮,并在脚本管理器的界面中确认安装。
  3. 刷新已打开的标签页,脚本即可立即生效。

💡 在 Chromium 内核浏览器中使用 Tampermonkey 时,需要在浏览器的扩展程序设置中为 Tampermonkey 开启“允许用户脚本”(Allow User Scripts),脚本才能运行。

Violentmonkey 在默认设置下运行用户脚本的时机晚于页面的第一个内联脚本(在 2.49.4 测试版中确认;在 MV2 版的“Synchronous page mode”下,用户脚本会先运行)。因此那个内联脚本读到的是未加噪声的值,还能事先替换内置函数,获知本脚本的管理器地址(名称和安装编号)以及设置(见下方的“已知局限”)。

请不要修改脚本头部的 @grant none、@run-at document-start、@inject-into page。哪怕只申请一项权限(@grant),管理器也会在隔离环境中运行脚本,导致无法修改页面的函数;如果不是 document-start,页面就会先读走原始值。


⚙️ 设置

没有单独的设置界面。请在脚本管理器中编辑本脚本,修改顶部的 CONFIG。

键默认值说明
canvastrue为画布、WebGL、WebGPU、VideoFrame 的读取以及 measureText 加入噪声
audiotrue为窗口和 iframe 中的音频读取加入噪声(音频 Worklet 的输入保持原始值)
webrtcfalse移除页面提供的 STUN、TURN 服务器。无法隐藏公网 IP,开启后视频通话可能无法连接
braveMode'auto''auto':该网站上 Brave Shields 的指纹保护正在生效时,关闭重叠的功能(canvas、audio);'on':始终关闭;'off':不会仅因浏览器是 Brave 而关闭
respectNativeCanvastrue如果浏览器或其他扩展已经在修改画布,则关闭画布噪声
smallReadsPerSecond2048让小范围读取(少于 256 像素且不超过画布的 1/4)可以不加噪声的预算(每秒像素数)。设为 0 则不设例外
uploadPixels131072为纹理上传、ImageBitmap、new VideoFrame(画布)、录制帧加入噪声的画布尺寸上限(约 360×360)。更大的画布经由这些途径输出时不加噪声
sites{}按网站设置的例外(见下文)
debugfalse在开发者工具控制台输出 [Shield] 日志(替换了 console.log 的页面代码也会收到这些日志)

1.7 版的 hardware、webglGpu、hideBrave、battery、workers、noiseScope、siteKeyHours、privateKeyHours 已在 1.8 版中删除。即使它们仍留在你修改过的副本中,也会被忽略。

按网站设置例外:在 sites 中写入域名(包括子域名),并为其指定 false(在该网站关闭)或要覆盖的设置。

sites: {
  'photopea.com': { canvas: false },            // 需要原样读取像素值的图像编辑器
  'meet.google.com': { webrtc: false },         // 开启 webrtc 时的视频通话网站
  'kepler.gl': { smallReadsPerSecond: 8192 },   // 拾取半径较大的地图可视化
  'example.com': false,                         // 在该网站关闭(不挂任何钩子)
},
  • 只要顶层页面或 iframe 自身的地址中有一个匹配即适用;多条规则匹配时,较长(更具体)的域名优先。
  • *.example.com、.example.com、大写字母以及国际化域名(如中文域名)都可以直接照写。
  • 在 canvas、audio、webrtc 全部关闭的页面上,不会挂任何钩子。不过,在 Tampermonkey 和 Violentmonkey 中,堆栈隔离会在读取设置之前进行,因此即使在已通过设置关闭本脚本的网站上,如果页面的 CSP 禁止 eval 或只报告 eval,仍可能产生相应的报告。
  • 偏离默认值的设置和按网站设置的规则(修改 smallReadsPerSecond、uploadPixels,只关闭 canvas、audio 中的一项,webrtc: true),都可能成为该网站把你和其他用户区分开来的线索。

📝 修改设置后,如果脚本自动更新,改过的部分可能会被新版本覆盖,因此请另外记下改过的设置。


⚠️ 注意事项

  1. 目标不是不被发现,而是让访问难以被关联。 绘制预先已知数值的图像进行比对,任何画布噪声都会暴露(用单色填充的图像,无论密钥如何,约有 3% 的像素会改变;这是中等亮度的情况,纯黑或纯白更少);CreepJS 等指纹检测网站显示检测到噪声,也属于正常现象。对于察觉到噪声并把画布、音频数值从哈希中排除的采集器,本脚本无效。
  2. 只处理部分指纹。 本脚本不会修改 IP 地址、字体、屏幕尺寸、时区、语言、User-Agent 和 Client Hints、GPU 名称、CPU 核心数、内存以及电池(原因见上方的“不作修改的数值”)。请与广告和跟踪拦截扩展或浏览器自带的保护功能一起使用。
  3. Worker 和音频 Worklet 中读到的是原始值。 1.8 版两者都不包装,因此页面只需一个 new Worker(blob) 就能读到未加噪声的画布值,而且这个值在不同网站上都相同。不透明源 iframe(sandbox、data:)也是如此。
  4. 会记住设备的网站可能每次访问都把你当作新设备,因为噪声密钥每次打开页面都会改变。如果银行、支付或登录网站每次都要求验证“新设备”,请只对该网站用 { canvas: false, audio: false } 关闭保护(该网站将看到未受保护的原始指纹)。
  5. 数值每次访问都会变化,这本身就可能成为痕迹。 通过登录认识你的网站可以比较你的各次访问,任何网站也都可以比较跨源 iframe 或两个已打开标签页中的数值,从而推测出本脚本的存在。噪声只是改变数值,并不能让你混入显示相同数值的用户群体之中。
  6. 浏览器的保护优先。 指纹保护在浏览器于所有地方统一施加时效果最好:Firefox 的指纹保护(FPP)和 resistFingerprinting、Brave Shields、Safari 的高级指纹保护。Tor Browser 和 Mullvad Browser 的做法是让所有用户显示相同的指纹,因此请不要在其中添加包括本脚本在内的用户脚本。
  7. 以 Chromium 内核浏览器(Chrome、Edge 等)为基准进行了优化。 文字尺寸噪声、画布录制保护和堆栈隔离都是按 Chromium 内核浏览器的行为设计的,未能在 Firefox 上测试。

🛠️ 故障排除

症状解决方法
在任何网站上都不生效请确认没有修改脚本头部;如果在 Chromium 内核浏览器上使用 Tampermonkey,还要确认已开启“允许用户脚本”
图像编辑器、绘图网站上的颜色有细微变化在 sites 中把该网站设为 { canvas: false }
在画布游戏、地图、3D 查看器中,点击或悬停的对象偶尔不对,或提示框闪烁{ smallReadsPerSecond: 8192 }(或更大)
频繁把画布作为 WebGL 纹理上传的小画面(标签、HUD)卡顿{ canvas: false }
银行、支付或登录网站每次都把你识别为新设备{ canvas: false, audio: false }(该网站将看到原始指纹)
视频通话无法连接(webrtc: true 时){ webrtc: false }
1.7 版中使用的设置(hardware、workers、siteKeyHours 等)不起作用这些设置已在 1.8 版中删除,会被忽略(见下方的“1.8 版更新内容”)。如果你曾为银行、支付网站设置 { siteKeyHours: 0 },请改为 { canvas: false, audio: false }
想确认脚本是否在工作设为 debug: true,在开发者工具控制台中查看 [Shield] 日志

🔬 了解更多

工作原理详解
  • 噪声密钥:每个脚本实例(脚本管理器注入并运行本脚本的每个文档各一个)在启动时用 crypto.getRandomValues 新生成一个 32 位密钥。密钥不会被存储、写入日志,也不会放在页面能读取的地方;本脚本也不读取 GM_info。
  • 确定性噪声:每一行中每 16 个像素选取一个像素,把该像素 R、G、B 中的一个通道调整为由密钥决定的配对的代表值(变化不超过 1)。坐标采用画布的绝对坐标,因此无论读取局部还是全部、以 8 位还是浮点数(float16)读取,得到的值都相同,而且多次应用结果不变(幂等)。导出时不改动原画布,而是导出加了噪声的副本。
  • 连半透明像素也覆盖:噪声加在 2D 画布存储半透明像素所用的级别上(预乘 Alpha),因此经过“读取 → 写回 → 再读取”,数值也不会出现偏差。这是因为只修改不透明像素的做法,只需一行 globalAlpha = 0.99 就能绕过。
  • 防范清除低位:配对方式由密钥在 {2k, 2k+1} 和整体偏移 1 的 {2k+1, 2k+2} 之间选定,因此即使页面先清除最低位(& 0xFE)再计算哈希,不同页面也不会得到相同的值。
  • 文字尺寸:Chromium 的 measureText 值是以 1/65536 px 为单位的 float32,若随意改动其低位,就会被 Math.fround(w) !== w 识破。因此只在这个网格内移动不超过一格。
  • 音频:每 8 个采样为一组,由密钥在组内选定一个采样,并把它的值移动 ±1 ulp。分组按信号中的绝对位置划分,因此 getChannelData、copyFromChannel 和 ScriptProcessor 的输入对同一采样给出相同的值。
  • 媒体路径:在画布和音频转换为媒体的地方(createImageBitmap(画布)、new VideoFrame(画布)、captureStream(),以及 createMediaStreamDestination() 前面一条极其微小的变换曲线)也会加入噪声,因此之后无论流向编码器、纹理、<video> 还是 WebRTC,数值都相同。
  • 隐蔽钩子:所有被修改的函数都是包装原函数的 Proxy。数字参数会在原生函数之前,按照与 WebIDL 相同的顺序只转换一次;钩子用到的内置函数在启动时就已保存,因此即使页面之后替换这些函数,也不受影响。
  • 堆栈隔离:如果堆栈中显示的脚本地址可能含有用户专属值,就以固定的名称(userscript-sandbox)通过间接 eval 重新加载脚本主体,并安装这个副本。在 about:blank 以外的文档中,eval 在脚本执行完毕后的 Promise 回调中调用,因此 eval 的 CSP 违规报告中不含本脚本的地址、行号和代码;在禁止 eval 的页面上,则改用由 Trusted Types 策略生成的内联 <script> 加载副本。
  • iframe 监控:在取得窗口的那一刻(contentWindow、window.open 等),以及插入节点的函数(appendChild、innerHTML、document.write 等,包括影子根中的插入)返回之后,立即安装同样的钩子;由 HTML 解析器插入的 iframe 会在下一个内联脚本运行之前完成安装,导航到其他文档的 iframe 则会在新文档的第一个脚本运行之前完成安装(剩余的空隙见下方的局限)。
已知局限详解
  • 多次读取后多数表决:噪声位置由画布坐标决定,因此把图像每次平移 1 像素绘制出三份副本,对其进行多数表决就能完全还原原始值;用放大 2 倍绘制的副本也几乎能全部还原。收集密钥不同的数值同样可以去除噪声:对三个各有自己密钥的跨源框架进行多数表决后,加了噪声的画布字节从 8,192 个中的 43 个减少到 3 个(不同访问的数值也是如此)。
  • 小范围读取预算:默认每秒 2,048 像素(最初 4,096 像素)以内的读取不加噪声。这只能减缓分块读取攻击,无法完全阻止(把 300×150 的画布以 15×15 的小块全部读完大约需要 20 秒,此为计算值);而且观察预算耗尽的时刻,也能得知脚本的存在。
  • 抗舍入能力弱:±1 的噪声无法改变经过粗略舍入的统计值(如把音频采样之和四舍五入保留五位小数、把文字宽度舍入到 1/1000 px)。
  • 大画布的上传与录制:大于 uploadPixels(约 360×360)的画布,通过纹理上传、ImageBitmap、new VideoFrame、captureStream 输出时不加噪声。想要更严格,可以调大这个值(偏离默认值后,可能会通过这个边界暴露你的设置)。
  • 非画布图像与其他 GPU 路径:把 <img> 或 SVG 图像作为纹理上传并在着色器中读回时,得到的是原始值(为了不破坏地形瓦片、LUT 等数据纹理)。用计算着色器(compute shader)转移后读取 WebGPU 的输出,或从本脚本不处理的格式(如 rgb10a2unorm)读取,得到的也是原始值。
  • 字体:通过 DOM 布局(getBoundingClientRect、offsetWidth 等)测得的文字宽度和已安装字体列表无法防护。曾经测试过相应的防护,但数值仍会从其他途径泄露,而且会拖慢或破坏网站,因此没有加入。字体需要浏览器层面的保护。
  • WebRTC 与公网 IP:webrtc: true 只会移除页面提供的 STUN、TURN 服务器,无法阻止想获知公网 IP 的网站(页面若把自己的服务器作为远端候选地址传入,浏览器就会直接向它发送 UDP 连通性检查)。页面也能察觉到这项设置已开启。要隐藏 IP,请使用浏览器的 WebRTC IP 处理策略,或关闭 WebRTC。
  • 堆栈中的管理器地址与 CSP 报告:在同时禁止 eval 和内联脚本的页面(包括只列出 'self' 和主机名的常见 script-src)以及 Firefox 上无法进行隔离,管理器地址中的用户专属值(Tampermonkey 的安装 ID 等)可能经由部分途径暴露。在 CSP 禁止或仅报告 eval 的页面上,每个文档(每条限制 eval 的策略)会产生一份 eval 的违规报告(about:blank 以外文档的报告中不含本脚本的地址、行号和代码)。在 eval 被禁止、改用内联 <script> 加载副本的页面上,每条禁止或仅报告这种内联脚本的策略还会再产生一份含有 chrome-extension 和本脚本固定行号的报告(1.7 版没有这种报告)。
  • 先运行的代码:比本脚本先运行的页面代码(在 Violentmonkey 的默认设置下,是页面的第一个内联脚本;此外还有页面事先动过手脚的新 iframe、弹出窗口的初始 about:blank 窗口)可以事先替换内置函数,从而取得本脚本从堆栈中读取的管理器地址中的用户专属值(Tampermonkey 的安装 ID、Violentmonkey 的名称和安装编号,在所有网站上都相同)以及设置(包括 sites 中的域名),还能决定或获知该窗口的噪声密钥(仅限那一次页面加载的密钥)。这类代码先行开启的性能分析器,也可能在安装前的样本中看到管理器地址。本版本没有修复这一点(1.7 版也是如此)。
  • 安装时机:进行隔离时,安装会推迟到脚本执行结束之后,因此在同一次执行中排在本脚本之后运行的代码(如果脚本管理器在用户脚本之间等待,下一个用户脚本也在其列)读到的是受保护之前的值。在本脚本之后单独运行的页面脚本,则会在安装完成之后运行。
  • 未捕获的错误:在用 eval 加载副本的窗口中,经由钩子抛出的未捕获错误会以不带位置和错误对象的 Script error. 传给页面,页面自身的错误收集会因此丢失这些信息(这是 1.8 版的变化;1.7 版会传出消息和错误对象,位置显示为 userscript-sandbox)。
  • iframe 的短暂空隙:存在页面能抢先接触新窗口的短暂空隙,例如在插入节点的调用过程中运行的代码、导航到 javascript: 地址的文档;HTML 中写入的封闭声明式影子根里的 iframe 则无法保护。
  • 速度:插入新的同源 iframe 的调用以及 new VideoFrame(画布) 会多花几毫秒。

📝 1.8 版更新内容

1.8 版重新审视了 1.7 版,修复了安全问题,并减少了脚本自身留下的痕迹。在此过程中,部分功能被有意删除;已删除的设置即使仍留在你修改过的副本中,也会被忽略。

  • 每次打开页面都重新生成噪声密钥(删除 noiseScope、siteKeyHours、privateKeyHours)。1.7 版用安装 ID 和修改时间生成按网站划分的密钥,因此一旦比本脚本先运行的代码,或事先对新窗口(初始 about:blank)动过手脚的页面取得了这些材料,就能算出该用户在所有网站上的密钥。现在本脚本不再读取 GM_info,也不存储密钥,因此这类代码能决定或获知的只有那一次页面加载的密钥(不过仍能取得管理器地址和设置,见已知局限中的“先运行的代码”)。作为代价,会记住设备的网站可能每次访问都把你当作新设备(如果在 1.7 版中为银行、支付网站设置了 { siteKeyHours: 0 },请改为 { canvas: false, audio: false })。
  • 删除了四项数值伪装(hardware、webglGpu、hideBrave、battery)。CPU 核心数和内存、GPU 名称、Brave 痕迹、电池都只能在窗口中修改,因此与同一页面的 sandbox iframe、Worker 和请求头中可见的真实数值相矛盾,而这种矛盾暴露了伪装。现在这一痕迹已经消失,但只读取窗口的采集器也会看到真实数值。
  • 删除了 Worker 包装(workers)。这项设置(默认关闭)开启时曾存在两个安全问题:重定向到其他源的 Worker 地址中的脚本可能会以本网站的源运行;在某些 CSP 下,页面能读到本网站的噪声密钥和全部设置。现在 Worker 始终读取原始值,这类重定向也会像原生行为一样失败。
  • 删除了音频 Worklet 包装。 原先即使在默认设置下,Worklet 中的页面代码也能从堆栈中取得存放本脚本主体的 blob: 地址,进而读到本网站的噪声密钥和全部设置(包括 sites 中的域名)。audio 仍会为窗口和 iframe 中的音频读取加入噪声。
  • 修复了标签页崩溃和 toBlob 回调不触发的问题(两者在 1.7 版中也存在)。此前,页面用另一个窗口的函数导出或读取画布时,Chrome 141 中的标签页可能会崩溃(在本脚本未能先行到达的同源窗口中,现在仍可能如此);而在初始空白窗口被新文档重新使用的同源 iframe 和弹出窗口中,toBlob 的回调曾无法触发。
  • 改进了堆栈隔离。 现在只在堆栈中的地址可能含有用户专属值时才进行隔离;eval 的 CSP 违规报告中不再包含本脚本的地址、行号和代码(about:blank 窗口除外);在禁止 eval 但允许内联脚本的页面上也会进行隔离(在连内联脚本也禁止的页面上,仍像以前一样运行原始脚本,并会多产生一份含有 chrome-extension 和固定行号的报告)。在 eval 或内联脚本可用的页面上,安装过程中堆栈和性能分析器样本里出现管理器地址的问题也已消除(原始脚本在安装前运行期间的样本中仍会出现)。作为代价,安装会推迟到脚本执行之后(见已知局限中的“安装时机”)。
  • 减少了脚本自身留下的痕迹。 消除了两类痕迹:脚本管理器也向同源 iframe 注入本脚本时,在父窗口已安装过的窗口上重复安装而能被 toString 识破的痕迹(开启画布噪声时,这项修复仅在 Chromium 内核浏览器上有效;重新导航的 iframe、以同源地址打开的弹出窗口等情况仍会留下这一痕迹);以及打开同源弹出窗口时,发往页面报告服务器的 COOP 违规报告。
  • 修复了 1.7 版的疏漏。 不再调用 Array.prototype 上的索引 getter;改为像原生代码一样读取传给 WebGPU 的字典;用 Range 插入影子根的 iframe 也会在插入时立即安装钩子。在无需保护的页面上不挂任何钩子和监听器;debug 日志即使失败,也不会跳过后续的安装。respectNativeCanvas 也会对每个窗口重新检查,堵住了以同源地址打开的弹出窗口中部分窗口(如 <embed> 窗口)读到原始画布的空隙。
  • 整理了代码并增加了测试。 整理时逐一确认:在测试覆盖的读取路径上,相同密钥下的输出与 1.7 版逐字节一致。

💬 欢迎反馈

如果发现出现异常的网站或新的绕过方法,请在反馈标签页留下网站地址或复现代码。我会逐一复现、判定并修复。


📜 许可协议

本脚本适用以下许可协议。中文译文旨在帮助理解,仅供参考;如与英文原文有出入,以英文原文为准。

Copyright (c) 2026 LiteWeaver. All Rights Reserved.

1. PERMITTED USE

You are permitted to use this script for personal, non-commercial purposes only. You may also change the settings in the CONFIG section of this script for your own personal use.

2. RESTRICTIONS

You may not reproduce, distribute, modify, create derivative works of, publicly display, or commercially exploit this software, in whole or in part, without explicit written permission from the copyright holder.

3. DISCLAIMER OF WARRANTY AND LIABILITY

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

中文参考译文

版权所有 (c) 2026 LiteWeaver。保留所有权利。

1. 允许的使用

您仅可将本脚本用于个人非商业用途。您也可以出于个人自用目的,更改本脚本 CONFIG 部分中的设置。

2. 限制

未经版权持有人明确的书面许可,您不得复制、分发、修改、公开展示或以商业方式利用本软件的全部或部分,也不得基于本软件的全部或部分创作衍生作品。

3. 担保与责任的免除

本软件由版权持有人“按原样”提供,版权持有人不作任何明示或暗示的担保,包括但不限于对适销性和特定用途适用性的暗示担保。在任何情况下,对于因使用本软件而以任何方式产生的任何直接、间接、附带、特殊、惩戒性或后果性损害(包括但不限于采购替代商品或服务;使用、数据或利润损失;或业务中断),无论其因何引起,也无论基于何种责任理论,不论是合同责任、严格责任还是侵权责任(包括过失或其他情形),即使已被告知发生此类损害的可能性,版权持有人均不承担责任。

Рейтинг: 0