当前位置: 首页 > news >正文

网站到底是如何通过JS读取你的浏览器指纹的?

在反爬虫与风控的对抗中,爬虫工程师常有一种错觉:我用了最新版的 Chrome,代理 IP 也很干净,为什么一访问就被拦截?原因在于,你的浏览器在打开网页的那一瞬间,就已经在风控的审视下“裸奔”了。

风控系统不需要你输入身份证号,它只通过一段几十 KB 的 JavaScript 代码,就能在毫秒级内给你的浏览器画出一幅精确到像素、时区和硬件毛细血管的“数字画像”。

本文将拆解网站是如何一步步读取你的浏览器指纹的。只有极致了解对方如何侦察,才能在指纹浏览器开发中做到精准反制。

一、 指纹采集的先锋:基础环境与系统特征

风控 JS 下发的第一波请求,是不需要任何计算复杂度的“明文特征”,它们挂在navigatorscreen对象上,是一切指纹关联的基石。

1. UserAgent 与高熵特征

不仅读取navigator.userAgent字符串,现代风控更看重navigator.userAgentData(Chrome 90+ 引入的 Client Hints API)。

// 风控代码示例:获取高熵特征,剥离伪造的 UAnavigator.userAgentData.getHighEntropyValues(["platform","platformVersion","architecture","model","uaFullVersion"]).then(ua=>{// 这里能拿到真实的操作系统架构(x86/arm)、Windows具体版本号// 如果你用JS强行改了UA字符串,但没改底层Client Hints,瞬间暴露});

2. 硬件并发与内存

这是判断设备算力的重要指标,也是区分服务器/模拟器与真实PC的关键。

letcores=navigator.hardwareConcurrency||0;// CPU逻辑核心数letmemory=navigator.deviceMemory||0;// 设备内存GB(受隐私策略限制,可能返回近似值)// 真实用户:cores通常是4,8,16;memory是4,8,16// 服务器/爬虫:cores动辄64,memory是32+,或者返回undefined(无头浏览器常见)

3. 屏幕与色彩深度

屏幕分辨率本身容易伪造,但风控看的是“组合逻辑”。

letscreenInfo={w:screen.width,// 屏幕物理宽度h:screen.height,// 屏幕物理高度aw:screen.availWidth,// 可用宽度(去除任务栏)ah:screen.availHeight,// 可用高度cd:screen.colorDepth,// 色深,通常为24或32dpr:window.devicePixelRatio// 设备像素比,Retina屏为2或3};// 矛盾检测:如果 screen.width=1920, 但 availHeight=1080(没有给任务栏留空间),大概率是虚拟屏幕// 矛盾检测:如果 dpr=1,但声称是 MacBook Retina 设备,直接判定伪造

4. 时区与语言环境

这是风控进行“时空一致性”校验的起点,与代理 IP 的地理位置强绑定。

lettimezone=Intl.DateTimeFormat().resolvedOptions().timeZone;// 如 "Asia/Shanghai"letlocale=navigator.language;// 如 "zh-CN"// 致命矛盾:IP归属地是美国,timezone却是Asia/Shanghai,语言是zh-CN,90%概率是爬虫

二、 深入硬件:高级渲染指纹

基础特征容易伪装,但 GPU 和声卡在执行渲染和计算时的物理微小差异,是无法通过简单修改 JS 变量伪造的。这是风控最核心的“杀招”。

1. Canvas 指纹:GPU 的独特笔迹

Canvas 指纹的原理是:让浏览器在画布上绘制特定图形和文字,由于 GPU 型号、驱动版本、底层渲染引擎(如 Skia/DirectWrite)的抗锯齿算法不同,最终生成的像素数据存在微小差异。
风控实战代码解析:

functiongetCanvasFingerprint(){letcanvas=document.createElement('canvas');letctx=canvas.getContext('2d');// 绘制文本:不同系统的字体渲染引擎(Mac/CoreText vs Win/GDI)差异极大ctx.textBaseline="top";ctx.font="14px 'Arial'";ctx.fillStyle="#f60";ctx.fillRect(125,1,62,20);ctx.fillStyle="#069";ctx.fillText("Hello, world! 🤖",2,15);// 加入Emoji,测试色彩支持// 绘制图形:测试混合模式与抗锯齿ctx.fillStyle="rgba(102, 204, 0, 0.7)";ctx.beginPath();ctx.arc(50,50,50,0,Math.PI*2,true);ctx.fill();// 提取像素数据并计算哈希letdataStr=canvas.toDataURL();// 风控不会把几MB的图片传回服务器,而是在本地计算哈希lethash=murmurhash3(dataStr);returnhash;}

反制难点:如果你用 JS Hook 拦截toDataURL返回一个假哈希,风控可以通过读取getImageData检查特定像素点的 RGBA 值是否与哈希匹配;如果你只改结果不改渲染,风控可以测量绘制操作耗费的时间(真实 GPU 绘制耗时与 CPU 模拟耗时差异巨大)。真正的指纹浏览器必须在 C++ 层(Skia 引擎)对输出的像素矩阵注入合法噪声。

2. WebGL 指纹:显卡的身份证

WebGL 提供了比 Canvas 更底层的 GPU 交互接口。风控不仅看渲染结果,更看 GPU 的身份参数。

functiongetWebGLFingerprint(){letcanvas=document.createElement('canvas');letgl=canvas.getContext('webgl')||canvas.getContext('experimental-webgl');letdebugInfo=gl.getExtension('WEBGL_debug_renderer_info');letvendor=gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);// 显卡厂商letrenderer=gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);// 显卡型号// 典型的暴露特征:// VMware/Gallium 3D -> 虚拟机// SwiftShader -> 无头模式/软件渲染// ANGLE (Intel/NVIDIA...) -> 真实PC// 此外,风控还会枚举WebGL支持的所有扩展列表(gl.getSupportedExtensions)// 不同的GPU和驱动支持的标准扩展集合不同,这又是一个高维特征}

3. AudioContext 指纹:声卡的回声

不播放任何声音,通过让浏览器处理音频信号,捕捉底层音频硬件和驱动处理的微小差异。

functiongetAudioFingerprint(){letcontext=new(window.AudioContext||window.webkitAudioContext)();letoscillator=context.createOscillator();letanalyser=context.createAnalyser();letgain=context.createGain();letscriptProcessor=context.createScriptProcessor(4096,1,1);oscillator.type='triangle';oscillator.frequency.setValueAtTime(10000,context.currentTime);gain.gain.setValueAtTime(0,context.currentTime);// 静音,用户听不见// 连接节点并渲染oscillator.connect(gain);gain.connect(analyser);analyser.connect(scriptProcessor);scriptProcessor.connect(context.destination);// 获取处理后的音频波形数据并计算哈希// 不同声卡对浮点数的计算精度、压缩算法不同,导致最终波形数据的极微小差异}

三、 系统级探测:字体与多媒体

1. 字体枚举指纹

系统安装的字体列表是高度个性化的,尤其是中文字体。风控通过测量特定字符在不同预设字体下的渲染宽度,来判断该字体是否存在。

functiondetectFonts(fontList){letbaseFonts=['monospace','sans-serif','serif'];lettestString="mmmmmmmmmmlli";lettestSize='72px';leth=document.getElementsByTagName("body")[0];lets=document.createElement("span");s.style.fontSize=testSize;s.innerHTML=testString;letdefaultWidths={};// 获取基础字体的宽度for(letfontofbaseFonts){s.style.fontFamily=font;h.appendChild(s);defaultWidths[font]=s.offsetWidth;h.removeChild(s);}letdetectedFonts=[];for(letfontoffontList){letfound=false;for(letbaseFontofbaseFonts){s.style.fontFamily=`'${font}',${baseFont}`;h.appendChild(s);// 如果宽度与基础字体不同,说明该字体被系统成功加载并渲染if(s.offsetWidth!==defaultWidths[baseFont]){found=true;break;}h.removeChild(s);}if(found)detectedFonts.push(font);}returndetectedFonts;}// 矛盾检测:声称是 Mac OS,却检测出微软雅黑和宋体,直接封杀

2. 媒体设备探测

摄像头、麦克风的存在与否及数量,也是环境真实性的佐证。

navigator.mediaDevices.enumerateDevices().then(devices=>{letaudioOutput=devices.filter(d=>d.kind==='audiooutput').length;letaudioInput=devices.filter(d=>d.kind==='audioinput').length;letvideoInput=devices.filter(d=>d.kind==='videoinput').length;// 无头浏览器或服务器通常返回 0 个设备});

四、 反侦察与对抗:风控如何识破 JS Hook

爬虫工程师常说:“我用了 Vue/React 的 Proxy,把navigatorCanvas全拦截了,为什么还是被查?”
因为现代风控拥有极其变态的“反反指纹”机制,专门检测 JS 运行环境是否被污染。

1. 属性描述符检测

原生对象的属性是内置的,其特性与通过Object.defineProperty劫持的属性完全不同。

// 爬虫常见的Hook:Object.defineProperty(navigator,'webdriver',{get:()=>undefined});// 风控反制检测:letdescriptor=Object.getOwnPropertyDescriptor(Navigator.prototype,'webdriver');if(descriptor&&descriptor.get&&descriptor.get.name!=='get webdriver'){// 原生的 getter 名称是 'get webdriver',如果你Hook了,name会变成 'get'// 或者 descriptor.configurable 变成了 true(原生一般是 false)return"环境被篡改!";}

2. 原型链与 toString 检测

原生函数(如toDataURL)转为字符串时,应输出[native code]

// 爬虫覆盖了 canvas.toDataURLcanvas.toDataURL=function(){returnfakeHash;};// 风控检测if(canvas.toDataURL.toString().indexOf('[native code]')===-1){return"函数被覆写!";}// 更狠的检测:直接去 iframe 中获取纯净的函数来对比

3. 降维隔离检测

风控 JS 会创建一个隐藏的、脱离当前文档流的<iframe>,获取 iframe 内部的navigatorcanvas等对象,与当前页面的对象进行对比。

letiframe=document.createElement('iframe');iframe.style.display='none';document.body.appendChild(iframe);letrealNavigator=iframe.contentWindow.navigator;// 如果当前页面的 navigator.webdriver !== realNavigator.webdriver// 说明你在当前页面做了全局 Hook,但 iframe 里的原生对象出卖了你

4. CDP 与 WebDriver 铁证

这是 Selenium/Playwright 无法根治的绝症。

// 检测1:最基础的 webdriver 标志navigator.webdriver===true;// CDP控制下默认为true// 检测2:Chrome 特有变量window.cdc_adoQpoasnfa76pfcZLmcfl_Array;// Chromedriver 注入的变量特征// 检测3:执行堆栈分析// 风控触发一个错误,检查 Error().stack// 如果堆栈中出现 'puppeteer'、'evaluateOnNewDocument' 等字眼,直接击毙

结语:通过上述拆解,我们可以得出一个残酷的结论:在 JS 层面进行的任何指纹伪装,都是掩耳盗铃。

无论你的 Proxy 写得多优雅,风控总能通过原型链、属性描述符、iframe 隔离和堆栈分析将你扒得底裤不剩。
传统爬虫在 JS 层的 Hook 对抗,已经走进了死胡同。这也正是指纹浏览器必须存在的根本原因。

真正的指纹浏览器,绝不依赖油猴脚本或 JS 注入。它的战场在 C++ 层:

  • Canvas/WebGL 伪装:修改 Chromium 的 Skia/ANGLE 引擎,在 GPU 计算完成后、返回给 JS 引擎之前,在内存中直接对像素矩阵注入合法噪声。
  • 属性篡改:直接修改 Blink 引擎的Navigator.idl和相关 C++ 类的返回值,让navigator.webdriver从编译层面就不存在,属性描述符依然是原生的。
  • 环境隔离:利用操作系统的沙箱和命名空间,让每个浏览器实例拥有独立且真实的设备映射。

在风控之眼面前,JS 层的伪装如同纸糊的面具;只有深入内核,重塑骨骼,才能在风控的凝视下隐入尘烟。这也是我们接下来探讨指纹浏览器底层开发的核心方向。

http://www.jsqmd.com/news/977663/

相关文章:

  • 如何3分钟搞定抖音批量下载:douyin-downloader完整指南
  • 门店预警通知能同时推送到钉钉、飞书、企业微信吗?企业级智能体多端协同技术全景解析
  • HoYo.Gacha:如何用本地工具安全管理你的米哈游抽卡记录?
  • 南京大学LaTeX论文模板:学术写作的终极效率革命
  • 3步轻松上手:ModTheSpire模组加载器完整使用指南
  • LLM无状态性实证:用20 Questions游戏解构大模型的‘思考’幻觉
  • 暗黑破坏神2存档编辑器完全指南:3步掌握d2s-editor核心功能
  • 【1.2Java基础】Win10环境变量配置详解-从原理到排雷
  • 手把手教你用纯C语言(仅stdio.h)实现SM4国密算法,附完整可运行代码
  • TlbbGmTool 天龙八部单机版GM工具完全指南:数据库管理与角色编辑实战教程
  • Sora核心骨干Gabriel离开OpenAI,要押上全部打造AGI前夜「最后产品」
  • ssm237基于SSM框架的校园招聘系统的设计与实现+vue(文档+源码)_kaic
  • 惠普暗影精灵笔记本终极控制指南:3步解锁完整性能
  • 如何快速掌握MCreator:面向新手的完整Minecraft模组制作指南
  • Unredacter:3大突破掌握像素化文本恢复,重塑数据安全认知边界
  • 如何3步快速清理重复视频:智能内容识别工具Vidupe完整指南
  • Redis 分布式锁进阶第五十六篇
  • 别再死记硬背了!用HFSS 2021 R2的主从边界(Primary/Secondary)搞定周期阵列天线,这篇保姆级教程带你避坑
  • 华为OD机试真题 新系统【最佳任务统筹】
  • Proteus 8.9 + Keil C51 实战:用单片机做个红绿灯,从仿真到代码保姆级教程
  • 新手也能看懂的BUUCTF SQL注入实战:从热点链接挖出后台数据库
  • 基于深度学习YOLOv8的晶圆体缺陷检测系统(YOLOv8+YOLO数据集+UI界面+Python项目源码+模型)
  • Meta与普林斯顿联合提出VLM³:标准VLM细粒度三维感知能力获系统评估
  • ssm239罪犯信息管理系统+vue(文档+源码)_kaic
  • 【论文阅读】RepoTransAgent: Multi-Agent LLM Framework for Repository-Aware Code Translation
  • Cyber Engine Tweaks 终极指南:5步掌握《赛博朋克2077》脚本开发与性能优化
  • Redis 分布式锁进阶第二篇讲解
  • 储能行业GEO优化实操指南:2026年如何选对服务商? - GEO优化
  • 2026年铝箱厂家推荐榜单:仪器仪表箱/拉杆仪器箱/铝合金化妆箱/航空箱/医疗设备箱及公文箱实力品牌精选 - 品牌发掘
  • 【高层次嘉宾 | JPCS出版,EI稳定快检索 |广东石油化工学院支持 | 已连续5届完成EI和Scopus检索,上一届会后3个月完成EI检索】第六届新材料与化学工程国际学术会议(AMCE 2026)