[英]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.