3

是否可以轻松检测用户对 DOM 的操作?

当用户在任何现代浏览器中使用控制台时,他/她可以以开发人员不希望的方式操作 DOM。

我有一个与处于某些状态的 DOM 非常相关的 Web 应用程序,如果用户通过控制台对 DOM 执行任何操作,我希望收到通知。

答案:

  1. 不需要与浏览器无关
  2. 不需要完美。我完全理解大多数(如果不是全部)方法都可以被规避,但我想要一个好的通用解决方案。
  3. 不能太纠结。我对在我的代码执行 DOM 操作时检查某些标志集的所有 DOM 事件注册事件处理程序不感兴趣

编辑

到目前为止,我收到的答案似乎有些混乱。正如上面 #2 中所指出的,我知道大多数(如果不是全部)方法都可以被规避。

此外,这是一个内部工具,因此受 VPN 保护。此外,还有服务器端检查。但是,有一些原因我无法详细说明,因为我想知道用户(数量很少)何时操纵了 DOM。

需要明确的是,这不是出于安全原因。我不是想在这里阻止恶意用户。更多地认为这是出于好奇。

4

6 回答 6

6

不要那样做。将您的网站编码为不信任用户输入,然后不关心用户做什么。如果提交了无效输入,则拒绝它。大家都开心。

很容易认为您拥有用户的浏览器。你没有。它为您服务,但仅在用户的一时兴起。

如果您真的必须知道 DOM 何时被修改——这似乎是一个非常脆弱的设计——那么只需做相当于计算校验和的事情。在站点批准功能的每个合法步骤之后,遍历您关心的 DOM 元素并记录它们的位置、值或您关心的任何内容。每隔一段时间、验证时间或下一次 UI 交互,进行比较。这是检测 DOM 更改的唯一全面的、跨浏览器(包括旧浏览器)的方法。现代浏览器提供 DOM 突变事件(有关更多详细信息,请参阅 Tim Down 的答案),但支持有限,并且显然将被另一个新事物取代,无论如何。

最终,您所做的任何事情都无法阻止决心击败您的计划的人。如果有的话,用户可以使用 Firebug 复制浏览器的 POST 请求,对其进行调整,然后编写一个小程序来提交他自己的恶意 POST 请求。保护您的服务器免受恶意输入比让您的网页防弹(因为它不会)更重要。

于 2012-11-24T00:09:11.153 回答
4

DOM 突变事件在所有主流浏览器的当前版本中都有效,并且可以做你想做的事。以下将涵盖整个文档中常见的 DOM 修改:

function handleDomChange(evt) {
    console.log("DOM changed via event of type " + evt.type);
}

document.addEventListener("DOMNodeInserted", handleDomChange, false);
document.addEventListener("DOMNodeRemoved", handleDomChange, false);
document.addEventListener("DOMCharacterDataModified", handleDomChange, false);

DOM 突变事件最终将被突变观察者所取代,后者在最近的 Mozilla 和 WebKit 浏览器中实现。

于 2012-11-24T00:23:18.433 回答
2

依靠脚本来防止或抵消对 DOM 的恶意编辑不是正确的方法。你到底在做什么取决于 DOM 没有被触及?似乎这本身就是一个巨大的危险信号。

于 2012-11-24T00:01:13.090 回答
1

我收到了很多答案,其中受访者提供了有关如何构建 Web 应用程序的建议。虽然这可能对某些读者有用,但这并不能回答问题。然而,有些人试图回答。我看到的最接近完整答案的是@Keith。唯一的问题是它未能通过“简单”测试。

正如一些人所说,正确的答案似乎是否定的——不可能轻易地检测到用户对 DOM 的操作。

于 2012-11-25T01:42:46.707 回答
1

这是一个非常有趣的问题,我认为 DOM 突变事件可能是最好的解决方案。我最初认为我可能会做的一件事是运行一个定时函数,它根据数据属性或 ID 检查 DOM 中的特定模块。如果我通过 JS 完全在客户端构建我的页面,我将为每个模块(DOM 元素,如:

<div id='weather-widget' data-module-type='widget'>
    <h1 data-module-name='weather'>Weather</h1>
    <!-- etc etc -->
</div>

无论如何,我的配置对象将包含所有这些内容,如模块类型、模块名称等:

//Widget configuration object
var weatherWidgetConfig = {
    type: 'widget',
    name: 'weather'
}

我会检查 DOM 元素及其所有子元素,以确保 data- 属性仍然与配置对象匹配,它们存在并且它们没有被更改。如果有,我会使用正确的配置再次调用 module.destroy() 和 module.build()。

于 2012-11-24T00:45:29.237 回答
0

我最近发现了“ Selector Listener ”,一种依靠 css 检测 DOM 变化的技术。它在 IE 9 中不起作用。将其应用于整个 DOM 听起来不是一个好主意,其目的是使用特定的选择器。

可以在此博客文章中找到更多详细信息。

于 2012-11-24T00:09:38.783 回答