You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Chrome扩展注入JS修改navigator.webdriver失效问题排查

解决Chrome扩展修改navigator.webdriver失效的问题

你的问题根源在于content script的沙箱隔离机制:你在content script里修改的navigator只是content script自身上下文的副本,页面全局的navigator对象完全没被改动——这就是为什么页面加载后,Selenium检测还是能读到true的原因。

下面是具体的修复方案:

1. 重构注入脚本,修改页面全局上下文的navigator

修改你的injected-javascript.js,通过注入script标签的方式,把代码直接运行在页面的全局环境中,而不是在content script的沙箱里:

// 要注入到页面全局的代码
const antiDetectScript = `
  // 重定义webdriver属性,强制返回false
  Object.defineProperty(navigator, 'webdriver', {
    get: () => false,
    enumerable: true,
    configurable: false // 防止属性被后续代码重新定义
  });

  // 针对某些网站的深层检测,额外处理wrappedJSObject(Chrome特殊环境下的包装对象)
  if (navigator.wrappedJSObject) {
    Object.defineProperty(navigator.wrappedJSObject, 'webdriver', {
      get: () => false,
      enumerable: true,
      configurable: false
    });
  }

  // 拦截任何试图修改webdriver的操作
  Object.defineProperty(navigator, 'webdriver', {
    set: () => {}, // 忽略所有设置该属性的尝试
  });
`;

// 创建script标签注入到页面最开头,确保在页面任何脚本运行前生效
const scriptEl = document.createElement('script');
scriptEl.textContent = antiDetectScript;
document.documentElement.insertBefore(scriptEl, document.documentElement.firstChild);
// 注入后移除标签,清理DOM
scriptEl.remove();

// 同时修改content script自身上下文的navigator,确保扩展内部检测也返回false
Object.defineProperty(navigator, 'webdriver', {
  get: () => false,
});

2. 优化Manifest配置,确保全局注入

更新你的manifest.json,添加all_frames: true确保所有嵌套iframe也能被注入,同时保留document_start的最早注入时机:

{
  "manifest_version": 2,
  "name": "webdriverInjector",
  "version": "1.0.0",
  "content_scripts": [
    {
      "matches": ["*://*/*"],
      "js": ["injected-javascript.js"],
      "run_at": "document_start",
      "all_frames": true // 覆盖所有页面层级
    }
  ],
  "permissions": ["*://*/*"]
}

3. 配合Selenium启动参数增强防护

如果你的Chrome版本在88以上,还可以添加Selenium启动参数,进一步绕过Chrome的原生自动化检测:

# Python Selenium示例
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
# 加载你的未打包扩展(替换为你的扩展文件夹路径)
chrome_options.add_argument('--load-extension=/path/to/your/unpacked-extension')
# 禁用Chrome的自动化控制检测
chrome_options.add_argument('--disable-blink-features=AutomationControlled')
# 解决某些环境下的沙箱限制
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')

driver = webdriver.Chrome(options=chrome_options)

验证方法

启动Selenium后,在页面控制台输入navigator.webdriver,应该返回false;或者在页面中执行以下代码确认:

console.log('navigator.webdriver:', navigator.webdriver);

这样修改后,页面全局的navigator.webdriver会被强制设为false,无论是页面自身的脚本还是Selenium的检测逻辑,都会读取到这个值。

内容的提问来源于stack exchange,提问作者RazorMx

火山引擎 最新活动