繁体   English   中英

从html中删除标签的方法的安全性问题

[英]Security concern over method of removing tags from html

我正在使用findAndReplaceDOMText ,这是一个允许您包装跨多个标签的文本的库。

考虑在以下html中的<em>标记中包装ob

<p>foo <span>bar</span></p>

它生成以下内容:

<p>fo<em>o </em><span><em>b</em>ar</span></p>

这非常有效。 我担心的是,我删除这些标签的策略可能会为注入代码提供可能性。 下面的代码确实有效,我只是担心潜在的代码注入机会,特别是因为我正在处理chrome扩展,所以目标页面的HTML可能会格式不正确。

import $ from 'jquery'

export default function clearMarks() {
  $(".deepSearch-highlight").parent().each(function() {
    const contents = []
    const $parent = $(this)
    $parent.contents().each(function() {
      const $node = $(this)
      let html

      if ($node.hasClass("deepSearch-highlight")) {
        html = $node.html()
      }
      else if (this.nodeName === "#text") {
        html = this.data
      }
      else {
        html = this.outerHTML
      }
      contents.push(html)
    })
    $parent.html(contents.join(""))
  })
}

我的目标是将html恢复到使用findAndReplaceDOMText进行转换之前的确切内容。 在“附加信息”部分中,您可以看到更简单的clearMarks函数将如何导致文本节点数量的更改。

我的策略是否有任何我缺少的安全漏洞? 是否有更安全/更优雅/更好的方式来实现我的目标?


附加信息:

  • 我正在使用findAndReplaceDOMText选项preset: "prose"

    忽略非文本元素(例如<script><svg><optgroup>, `等)

  • $(this).replaceWith($(this).html())一下,更简单的$(this).replaceWith($(this).html())导致文本节点数量激增。 通过上面的例子,我们得出: <p>"fo""o "<span>"b""ar"</span></p> (其中文本节点用"表示。)这会导致问题,如果你尝试重新应用findAndReplaceDOMText除了一般臭。

  • 插入的span元素有一个.deepSearch-highlight类(与上面的示例形成对比,后者将文本包装在em 。请参阅下面的完整代码。

import $ from "jquery"
import findAndReplaceDomText from "findandreplacedomtext"

import buildRegex from "../../shared/buildRegex"
import scrollToElement from "./scrollToElement"


export default function search(queryParams) {
  const regex = buildRegex(queryParams)
  findAndReplaceDomText($('body')[0], {
    find: regex,
    replace: createHighlight,
    preset: "prose",
    filterElements,
  })
  scrollToElement($(".deepSearch-current-highlight"))
}

function createHighlight(portion, match) {
  var wrapped = document.createElement("span")
  var wrappedClasses = "deepSearch-highlight"
  if (match.index === 0) {
    wrappedClasses += " deepSearch-current-highlight"
  }
  wrapped.setAttribute("class", wrappedClasses)
  wrapped.setAttribute("data-highlight-index", match.index)
  wrapped.appendChild(document.createTextNode(portion.text))
  return wrapped
}

function filterElements(elem) {
  const $elem = $(elem)
  return $elem.is(":visible") && !$elem.attr("aria-hidden")
}

如果您只想删除元素并保留其文本子项,请不要处理HTML。 您应该使用移动文本和元素节点的纯DOM API。 使用HTML解析器最多会产生次优的性能,并在最坏的情况下产生安全漏洞。

顺便说一下,更简单的$(this).replaceWith($(this).html())会导致文本节点数量激增。

这可以通过将Node.normalize()应用于祖先来解决。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM