一聚教程网:一个值得你收藏的教程网站

热门教程

如何利用 MutationObserver 监控并防止恶意浏览器脚本修改网页中受法律保护的内容声明

时间:2026-07-27 09:57:00 编辑:袖梨 来源:一聚教程网

应精准监听法律声明容器节点,仅启用childList、subtree、attributes(限定class/style/hidden)、characterData,禁用旧值比对;回调中验证目标归属、过滤恶意节点、检查隐藏属性与文本篡改,修复前断开观察或延时执行,防止死循环。

监控法律声明容器的 DOM 变更

必须限定观察范围,不能监听 document.body 或整个 document——这会捕获大量无关变更,导致误报、性能下降,甚至被恶意脚本利用回调逻辑制造死循环。真实场景中,法律声明通常位于固定容器内,比如 id="legal-notice"class="copyright-statement"

正确做法是:先用 document.querySelector 精准获取该容器节点,再传给 MutationObserver 实例:

const noticeEl = document.querySelector('#legal-notice') ||                  document.querySelector('.copyright-statement');if (!noticeEl) return; // 容器不存在,不启动监控

注意:不要依赖第三方插件动态生成的 class 名(如含时间戳或哈希值),优先使用语义化、稳定不变的 id 或带 data- 前缀的属性锚定。

只订阅真正危险的变更类型

法律声明被篡改,常见手法是替换文本、删除节点、注入广告标签、修改 style 隐藏原文。不需要监听所有变化,应关闭冗余选项:

  • childList: true —— 必开,用于捕获 <div> 被替换成广告 <iframe> 或整段被 remove()
  • subtree: true —— 必开,确保子树内任意层级的篡改(如嵌套 <span> 里插入水印)都能被捕获
  • attributes: true + attributeFilter: ['class', 'style', 'hidden'] —— 限制只关注可能用于隐藏/伪装的属性
  • characterData: true —— 必开,防止直接修改文本节点内容(例如把“版权所有”改成“授权转载”)
  • attributeOldValue: falsecharacterDataOldValue: false —— 不需要比对旧值,只需触发即响应

省略 subtree 会导致深层篡改完全漏报;开启 attributes 却不设 attributeFilter 会平白增加 30%+ 回调开销。

在回调中识别并阻断非法操作

回调函数不是日志记录器,它要能区分“用户正常编辑”和“脚本批量注入”。关键判断逻辑必须轻量且可靠:

  • 检查 mutation.target 是否属于声明容器或其后代(用 noticeEl.contains(mutation.target)
  • mutation.type === 'childList',遍历 mutation.addedNodes,过滤出含 scriptiframead-bannertaboola- 等特征的节点
  • mutation.type === 'attributes'mutation.attributeName === 'style',检查 mutation.target.style.display === 'none'visibility === 'hidden'
  • mutation.type === 'characterData',用正则粗筛是否包含关键词丢失(如“©”、“版权所有”、“保留所有权利”消失)

一旦确认非法,立即执行修复:用 noticeEl.replaceWith(noticeEl.cloneNode(true)) 恢复原始结构,避免 innerHTML 引发事件重绑或脚本重执行。

避免修复动作触发二次观察

这是最容易翻车的环节。在回调里直接调用 noticeEl.remove()noticeEl.textContent = ...,会再次触发 MutationObserver,形成无限循环,最终卡死页面。

安全做法只有两种:

  • 临时断开观察:在修复前调用 observer.disconnect(),修复完成后再 observer.observe(...)
  • setTimeout 延迟修复(延迟 0ms 即可),让当前批 mutation 处理完再操作 DOM,避开同一轮事件循环

别忘了加 try/catch 包裹整个回调体——恶意脚本可能故意抛错中断你的监控逻辑,而你无法控制它的行为。

真正难的是 iframe 注入和 document.write 场景,MutationObserver 对这两者完全无感,得靠 window.addEventListener('load', ...)iframe.onload 补位检测。

热门栏目