You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止Error对象的stack属性被篡改及拦截Tampermonkey脚本?

应对Tampermonkey脚本的解决方案

一、阻止Error对象的stack属性被篡改

要保护Error的stack不被第三方脚本篡改,核心是锁定stack属性的可写性,或者在错误实例创建时就冻结它,让后续代码无法修改。

方案1:冻结Error实例

重写全局Error构造函数,创建错误实例后立即冻结,阻止任何属性修改:

// 保存原生Error构造函数
const OriginalError = window.Error;
window.Error = function(...args) {
  const err = new OriginalError(...args);
  // 冻结实例,所有属性变为只读、不可配置
  Object.freeze(err);
  return err;
};

// 同理覆盖其他错误类型(如TypeError、ReferenceError)
const errorTypes = ['TypeError', 'ReferenceError', 'RangeError', 'SyntaxError'];
errorTypes.forEach(type => {
  window[`Original${type}`] = window[type];
  window[type] = function(...args) {
    const err = new window[`Original${type}`](...args);
    Object.freeze(err);
    return err;
  };
});

这种方式下,任何试图修改err.stack的操作都会直接失败(严格模式下抛出错误,非严格模式下静默失效)。

方案2:锁定Error.prototype的stack属性

通过Object.defineProperty把Error.prototype.stack设为不可写、不可配置,从原型层面阻止篡改:

// 获取原生stack属性的描述符
const originalStackDesc = Object.getOwnPropertyDescriptor(Error.prototype, 'stack');
// 重新定义为不可写、不可配置
Object.defineProperty(Error.prototype, 'stack', {
  ...originalStackDesc,
  writable: false,
  configurable: false
});

这个方案能阻止第三方脚本通过err.stack = 'xxx'或者重新定义stack属性来篡改,但需要确保你的代码在Tampermonkey脚本之前执行。


二、阻止Tampermonkey脚本加载或运行的实用方法

1. 拦截脚本注入(DOM层面)

Tampermonkey会向页面插入script标签,我们可以在DOM节点插入的捕获阶段拦截并移除这些脚本:

document.addEventListener('DOMNodeInserted', (e) => {
  const target = e.target;
  if (target.tagName !== 'SCRIPT') return;
  
  // 识别Tampermonkey脚本:要么包含用户脚本头,要么来源是Tampermonkey的内部URL
  if (target.textContent.includes('// ==UserScript==') || target.src.includes('tampermonkey')) {
    target.remove();
  }
}, true); // 使用捕获阶段,确保在脚本执行前拦截

2. 禁用Tampermonkey核心API

Tampermonkey会在全局暴露GM_*系列API(如GM_xmlhttpRequest、GM_addStyle),提前覆盖这些API让它们失效:

// 遍历并覆盖所有GM_开头的函数
Object.keys(window).forEach(key => {
  if (key.startsWith('GM_')) {
    window[key] = function() {
      throw new Error('Tampermonkey API is blocked');
    };
    // 锁定属性,防止被重新赋值
    Object.defineProperty(window, key, { writable: false, configurable: false });
  }
});

3. 利用Content Security Policy(CSP)

如果是你自己的网站,在HTTP响应头设置严格的CSP规则,禁止加载第三方脚本:

Content-Security-Policy: script-src 'self' https://your-trusted-cdn.com; object-src 'none'; base-uri 'self';

这种方式能从根源上阻止Tampermonkey注入的脚本(无论是inline还是外部源)执行,但需要服务器端配合配置。

4. 检测并终止第三方脚本执行

通过错误栈检测是否有Tampermonkey脚本在运行,一旦检测到就抛出错误终止执行:

function blockTampermonkey() {
  try {
    throw new Error();
  } catch (err) {
    const stack = err.stack;
    // 匹配Tampermonkey相关的栈信息
    if (stack.includes('tampermonkey') || stack.includes('userscript')) {
      throw new Error('Unauthorized script execution blocked');
    }
  }
}

// 在关键业务函数前调用,或者定时检测
setInterval(blockTampermonkey, 100);

注意:所有上述方案的核心前提是你的代码要比Tampermonkey脚本更早执行——如果是自己的网站,把防护脚本放在<head>的最顶部;如果是前端代码,确保脚本注入时机为document-start。

内容的提问来源于stack exchange,提问作者some dumb guy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 21:39:17