HTML Javascript - 防止从 dom 树的子节点执行脚本

Posted

技术标签:

【中文标题】HTML Javascript - 防止从 dom 树的子节点执行脚本【英文标题】:HTML Javascript - Prevent script execution from child nodes of a dom tree 【发布时间】:2012-09-19 03:59:10 【问题描述】:

我从一个不可靠的来源下载了一些 html 树,并使用它在我的页面中将内容显示为某个 HTML div 的子项。但是,此下载的代码存在运行脚本/或在事件处理程序中执行脚本的危险。是否可以在 HTML 中就像使用标签来定义脚本一样,做一个

<noscriptex>
    <script>
        ...
    </script>
</noscriptex>

那么浏览器不会执行这个标签内的任何代码?

如果没有这样的东西,我如何清理下载的 HTML 以显示带有 CSS 的 DOM 元素而不涉及任何脚本?

【问题讨论】:

您需要重新考虑这一点并在显示之前清理您的输入。像这样的代码正在等待被利用。 @Blender:这正是他所要求的, @Slaks:我的错。我不知何故错过了问题的最后一段...... 【参考方案1】:

没有;没有这样的功能。

相反,您需要解析 HTML 并使用严格的白名单删除任何无法识别的标签和属性。

您还需要验证属性值;尤其是 URL。

【讨论】:

无需解析,DOM 可用于查找和删除脚本元素而不执行它们。属性值更严格,也许所有的处理程序(on*)都可以设置为未定义? @RobG 谢谢,这是一个更好的建议,但遗憾的是代码和数据一起存在,但对文件系统或虚拟内存代码与数据页中的数据没有执行保护。我不确定是否所有处理程序都可以设置为未定义,甚至在至少一些 onLoad 和 onCreate 类型被调用之前。 @SLaks 编写解析器对我来说很昂贵,但我正在考虑。 我在问这个问题之前用谷歌搜索了这些,但事实证明已经有工具了。请参阅related 以及更多关于***【参考方案2】:

您可以使用函数从标记中删除脚本,例如

function stripScripts(markup) 

    var div = document.createElement('div');
    var frag = document.createDocumentFragment();

    div.innerHTML = markup;

    var scripts = div.getElementsByTagName('script');
    var i = scripts.length;

    while (i--) 
      scripts[i].parentNode.removeChild(scripts[i]);
    

    while (div.firstChild) 
      frag.appendChild(div.firstChild);
    
    return frag;

使用 innerHTML 插入的任何脚本元素都不会执行,因此它们是安全的。它们也不在 DOM 中,因此功能有限。

注意createDocumentFragment返回的对象可以直接插入DOM,函数返回的片段没有脚本元素。

【讨论】:

请记住,除了&lt;script&gt; 标签(例如javascript: URL 或内联事件处理程序)之外,还有其他方法可以获取内容中的脚本。 是的,当然。但是,如果 OP 要在页面中插入来自其他站点的标记,则任何事情都可能发生。【参考方案3】:

这就是 iframe 的用途。如果内容来自与主机页面不同的域,则不允许与任何其他内容进行通信。你可以让它运行脚本到它的核心内容,它们不会影响你的页面部分。

【讨论】:

脚本仍然可以做坏事。但我想这是我能得到的最多了! @foobarometer - 你认为它可以做什么样的坏事你试图防止。 我不希望用户认为我的网站很糟糕,即使它启动了 alert() 或更糟糕的事情,例如检测 Windows 并创建 ActiveXObjects。 @foobarometer - 确保这一点的唯一方法是只接受高度过滤的内容(比如只接受文本或只接受带有一些格式代码的文本),而不是通用 HTML。公告板使用自己的格式代码并且通常不接受 HTML 是有原因的。 这意味着我必须像公告板的人一样为我需要的东西发明一个我自己的标记,但我需要的很简单:HTML 的表示层。这在我看来是非常破碎的。执行此操作的正确位置是具有一些执行预防功能的浏览器。尽管如此,为了解决手头的问题,我倾向于使用可以转换为 HTML 的自定义标记。

以上是关于HTML Javascript - 防止从 dom 树的子节点执行脚本的主要内容,如果未能解决你的问题,请参考以下文章

防止 DOM 滞后

使用 Localstorage 将 javascript 变量从一个 html 页面存储和检索到另一个 (DOM)

防止图像在非 DOM jQuery AJAX 解析上加载

javaScript操作DOM对象

JavaScript DOM操作浅谈

使用 JavaScript 从 DOM 中删除表单