JQuery - 添加常规 HTML 以及转义 HTML

JQuery - Add regular HTML along with escaped HTML

我将一些数据存储在 firebase 中(可以在客户端中检索),然后,我使用 JQuery 将其添加到 HTML。这很简单 - 我只是将数据添加到 DOM 元素。然而,问题是,这个原始代码很容易受到攻击,所以我需要在将它添加到 HTML 之前正确地转义从数据库中获取的数据。我认为以下代码可以完成这项工作:

function escapeHTML(text) {
  var map = {
    '&': '&',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#039;'
  };
  return text.replace(/[&<>"']/g, function(m) { return map[m]; });
}

$('#element').prepend('<h1>Heading</h1><p>' + escapeHTML(data) + '</p>');

当我测试此代码时,通过使数据的值类似于 <script>alert('This should not work');</script>,我认为它只会将此文本添加到 <p></p> 标记,而不执行 JS,但它实际上 运行 代码。

我知道使用 $('#element').text() 会为我转义文本,但我不希望所有内容都被转义 - 我仍然想添加 <h1></h1><p></p> 标签,我只需要转义变量 "data" 。我看到了几篇关于类似主题的 Whosebug 帖子,但其中 none 似乎解决了这个问题 - post 1, post 2, post 3.

你问题中的代码不起作用的原因是因为 Javascript 中的 &amp; 等所有实体在 [=30= 中的 JS 时被解析为它们代表的字符] 被解析。如果将代码放在外部 .js 文件中,它会起作用,因为它不会被解析为 HTML。或者您可以对它们进行双重编码:

  var map = {
    '&': '&amp;amp;',
    '<': '&amp;lt;',
    '>': '&amp;gt;',
    '"': '&amp;quot;',
    "'": '&amp;#039;'
  };

但更好的方法是分别创建 <h1><p> 元素,并使用 jQuery 方法将转义文本放入段落中。

const data = '<scr' + 'ipt>alert("foo");</scr' + 'ipt>';

$("#element").prepend("<h1>Heading</h1>", $("<p>", {text: data}));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="element"></div>

如果要填写数据属性,同样可以:

$("#element").prepend($("<div>", {
    data: {
        attr: data,
        another: someMoreData
    },
    text: "hello world"
}));