简介:本文从浏览器自动化工具被站点识别的底层原理出发,系统讲解前端检测脚本的运行机制、代理拦截的技术原理及防御视角下的应对示例,并补充 HTTPS 证书配置、替换误匹配风险等实操细节。文章明确限定于授权测试与安全研究场景,帮助读者理解检测逻辑与合规边界,避免误用。
本文内容仅用于已获得授权的自动化测试、安全研究或个人学习场景,请严格遵守目标平台服务条款与相关法律法规。
在从事电商、生活服务、内容平台等场景的数据采集或自动化测试时,不少开发者会遇到一个棘手问题:明明已经完成了登录、滑块验证、滚动操作等一系列人工模拟,服务端却依然返回异常提示,甚至直接阻断后续请求。排查 network 面板与 console 日志后往往发现,问题并非出在操作流程本身,而是执行这些操作的”运行环境”已经被目标站点的前端脚本识别出来。
这类识别通常不依赖用户行为,而是通过读取浏览器全局对象中的某些特征字段来完成。一旦命中,站点即可在请求发出前或响应返回后注入异常逻辑,导致自动化流程失败。因此,应对思路需要从”理解检测逻辑”入手,而非继续在行为模拟层面打转。本文将从技术原理分析与防御视角出发,提供可参考的分析框架,不鼓励也不提供可直接用于违规操作的完整绕过步骤。
现代浏览器在正常访问网页时,会暴露一个全局对象(如 navigator、window),其中包含了与浏览器交互所需的各类接口。自动化控制工具在接管浏览器时,为了实现对页面元素的查找、点击、输入、执行脚本等操作,会向该全局对象中注入一些额外字段或方法。这些字段的名称通常具有一定规律,例如包含”driver””webdriver””selenium””Chrome”等关键词。
目标站点的前端脚本会主动遍历这些字段。例如,脚本可能在页面加载完成后执行类似以下的检测逻辑:
if (navigator.webdriver || window.__driver_evaluate || window.__webdriver_evaluate) {// 判定为自动化环境,触发风控逻辑document.body.innerHTML = '访问异常';}
一旦命中任何一个字段,站点就可以选择拒绝渲染页面、返回错误提示、隐藏关键数据,甚至在后续接口请求中植入无效参数。更隐蔽的做法是,前端脚本并不立即报错,而是将检测结果作为标记随请求发送到服务端,由服务端决定是否返回真实数据。这种情况下,仅从页面表现上很难直接发现问题。
因此,应对的关键不在于让自动化工具”消失”,而在于理解前端检测的运行逻辑,从而在授权测试框架内进行针对性分析。
既然识别逻辑存在于前端脚本中,那么一个自然的分析方向就是理解这些脚本的工作方式,并在测试环境中模拟其检测流程,以便在正式部署前提前发现问题。需要强调的是,以下内容仅作为技术原理分析与防御视角示例,不构成可直接执行的绕过指南。
中间人代理的作用是接管客户端与服务器之间的所有 HTTP/HTTPS 请求与响应。当浏览器请求某个 JavaScript 文件时,响应内容会先经过代理,再由代理转发给浏览器。从防御视角看,安全团队可以利用相同原理,在代理层对响应进行审计,检查是否存在异常的特征检测逻辑。
对于测试人员而言,理解这一原理的价值在于:可以在本地搭建代理环境,观察目标站点究竟下发了哪些检测脚本、检测逻辑如何编写,从而在授权范围内评估自身自动化方案的抗检测能力。
要实现上述分析,首先需要在本地搭建一个可编程的代理服务。常见做法是使用支持脚本扩展的代理工具,例如在命令行中安装相应的 Python 包:
pip install mitmproxy
安装完成后,需要将本机浏览器的代理设置为本地地址,例如 127.0.0.1:8001,确保所有浏览器流量都经过该代理。
HTTPS 证书信任配置(重要步骤): 由于目标站点通常使用 HTTPS,代理需要生成并安装本地 CA 证书。具体步骤如下:
mitmproxy --certs ~/.mitmproxy,工具会自动在对应目录生成 CA 证书文件;http://mitm.it,下载对应系统的证书文件;随后启动代理服务。Windows 环境下可以使用无交互界面的命令:
mitmdump -p 8001
Linux 环境下可使用交互式命令:
mitmproxy -p 8001
此时,所有经过浏览器的请求和响应都会被代理捕获,为后续的脚本化分析提供基础。
代理启动后,下一步是找出哪个 JavaScript 文件承担了环境检测任务。这需要借助浏览器开发者工具与代理面板。
打开目标站点,进入开发者工具的”网络”面板,刷新页面并观察加载的脚本资源。通常可以根据文件名进行初步筛选,例如某些站点会使用名称中包含”yoda””shield””risk””detect””guard”等关键词的文件来集中处理风控逻辑。如果文件名本身不具有明显特征,则需要进一步查看脚本内容,搜索”webdriver””driver_evaluate”等关键词。
同时,在代理面板中查看对应响应体内容,确认该脚本是否确实包含检测逻辑。定位到具体文件后,记录其 URL 路径特征,例如检测脚本的路径可能包含 /js/yoda. 这样的片段。
以下为通用改写框架示例,需根据目标站点调整,仅用于授权测试环境下的原理验证。
代理工具有一个关键能力:允许开发者编写 Python 脚本,并在每个响应返回时执行自定义逻辑。从原理分析角度,可以观察以下模式:
import refrom mitmproxy import ctxdef response(flow):# 根据路径特征匹配检测脚本(仅作原理示例)if '/js/yoda.' in flow.request.url:# 常见的自动化工具特征字段webdriver_keys = ['webdriver','__driver_evaluate','__webdriver_evaluate','__selenium_evaluate','__fxdriver_evaluate','__driver_unwrapped','__webdriver_unwrapped','__selenium_unwrapped','__fxdriver_unwrapped','_Selenium_IDE_Recorder','_selenium','calledSelenium','_WEBDRIVER_ELEM_CACHE','ChromeDriverw','driver-evaluate','webdriver-evaluate','selenium-evaluate','webdriverCommand','webdriver-evaluate-response','__webdriverFunc','__webdriver_script_fn','__$webdriverAsyncExecutor','__lastWatirAlert','__lastWatirConfirm','__lastWatirPrompt','$chrome_asyncScriptInfo','$cdc_asdjflasutopfhvcZLmcfl_']for key in webdriver_keys:ctx.log.info('Remove "{}" from {}.'.format(key, flow.request.url))# 将字段名替换为不存在的属性,使检测条件读取为 undefined# 注意:简单字符串替换可能误匹配正常代码中的同名变量,# 生产环境需结合上下文或正则边界判断flow.response.text = flow.response.text.replace('"{}"'.format(key), '"NO-SUCH-ATTR"')# 针对常见布尔检测的额外处理# 注意:将 'ChromeDriver' 替换为空串可能破坏脚本中的正常引用,# 更安全的做法是替换为假值属性名flow.response.text = flow.response.text.replace('ChromeDriver', '"NO-SUCH-ATTR"')flow.response.text = flow.response.text.replace('t.webdriver', 'false')
这段代码的核心逻辑可分为三层:
第一层是路径匹配。只有检测脚本的响应才会被修改,避免影响其他正常脚本的执行。
第二层是特征字段替换。将脚本中出现的已知特征字段名替换为 NO-SUCH-ATTR。由于这些字段在浏览器全局对象中并不存在,检测逻辑读取到的将是 undefined,条件判断自然为假。但需注意,简单字符串替换存在误匹配风险,例如正常代码中可能包含同名变量,生产环境需结合正则边界或更精细的 AST 解析。
第三层是布尔值覆盖。有些脚本可能直接访问 navigator.webdriver 并判断其真假。通过将相关语句替换为 false,可以确保即使字段存在,检测结果也不会命中。
完成分析脚本后,需要重新启动代理并加载该脚本。以监听 8001 端口为例:
mitmdump -p 8001 -s DriverPass.py
启动后,打开浏览器访问目标站点,观察代理日志中是否输出 Remove "xxx" from xxx 的记录。如果日志正常打印,说明检测脚本已被拦截并改写。
验证时请按以下优先级检查:
| 优先级 | 检查项 | 说明 |
|---|---|---|
| 高 | 页面是否正常渲染 | 不再出现访问异常提示 |
| 高 | 接口数据是否完整 | 关键字段未被隐藏或篡改 |
| 中 | Cookie 是否正常获取 | 登录态可持续使用 |
| 中 | 连续请求是否稳定 | 未触发服务端风控封锁 |
| 低 | 日志是否记录完整 | 便于后续排查 |
重要停止条件: 若经过多轮调整后仍然失败,应立即停止尝试并重新评估方案的合规性与可行性,而非继续加大绕过力度。持续尝试可能触发目标站点更严格的风控策略,甚至导致法律风险。
上述基于响应改写的方案在多数分析场景下有效,但也有明显的局限性。
如果检测逻辑被打包进大型脚本中,路径匹配可能不够精准,需要结合更多上下文特征进行判断。此时可以考虑在代理层解析响应内容中的关键词,而不是仅依赖 URL 路径。
如果站点采用服务端校验,即前端仅收集特征并通过加密参数回传,服务端再判断是否异常,那么仅靠改写前端脚本可能不够。此时需要进一步分析参数生成逻辑,在请求发出前调整参数内容。
如果站点使用多文件协同检测,即多个脚本互相配合,任何一个脚本未加载都会触发异常,则需要保证所有相关脚本都被正确处理。
如果需要保持长期稳定运行,建议将拦截代理封装为独立的服务模块,并与自动化任务调度系统集成。同时做好日志记录,便于在检测规则更新后快速定位新的特征字段。
以下是常见代理工具的简要对比,供选择参考:
| 工具 | 平台 | 脚本扩展 | HTTPS 支持 | 适用场景 |
|---|---|---|---|---|
| mitmproxy | 跨平台 | Python | 需手动安装证书 | 自动化分析、批量处理 |
| Fiddler | Windows/macOS | C#/JS | 自动信任 | 可视化调试、快速定位 |
| Charles | 跨平台 | 有限 | 需手动安装证书 | 移动端抓包、接口分析 |
在使用任何代理拦截或脚本改写技术之前,请务必确认以下事项:
本文所有技术内容仅面向安全研究人员、已获授权的测试工程师及相关从业者,不对任何违规使用行为承担责任。
需要注意的是,上述技术手段仅应用于合法的自动化测试、个人学习或已获得授权的数据采集场景。对于存在明确服务条款限制的平台,应严格遵守相关规定,避免对目标系统造成不必要的压力。
此外,通过中间人代理拦截 HTTPS 流量需要安装本地证书,这意味着客户端环境需要能够完成证书信任配置。在服务器或无图形界面环境中部署时,应提前确认证书安装流程是否可行。
总之,应对自动化工具被识别的核心在于理解前端检测的运行逻辑,并在合规框架内通过代理技术对检测脚本进行原理分析。掌握这一思路后,无论目标站点如何调整特征字段,开发者都能够以较低成本完成评估,但效果取决于站点策略与授权范围,不保证任何成功率。