使用jQuery转义HTML

时间:2011-05-16 16:56:46

标签: javascript jquery html escaping

我想出了一个使用jQuery来逃避HTML的黑客攻击,我想知道是否有人发现它有问题。

$('<i></i>').text(TEXT_TO_ESCAPE).html();

<i>标签只是一个假人,因为jQuery需要一个容器来设置文本。

是否有更简单的方法可以做到这一点?请注意,我需要存储在变量中的文本,而不是用于显示(否则我只能调用elem.text(TEXT_TO_ESCAPE);)。

谢谢!

3 个答案:

答案 0 :(得分:62)

这是一种非常标准的方式,我的版本使用<div>但是:

return $('<div/>').text(t).html();

虽然迈克塞缪尔指出,但这在技术上并非100%安全,但在实践中它可能非常安全。

当前的Prototype.js执行此操作:

function escapeHTML() {
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
}

但它曾经使用“在div中放置文本并提取HTML”技巧。

还有_.escape in Underscore,就像这样:

// List of HTML entities for escaping.
var htmlEscapes = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  "'": '&#x27;',
  '/': '&#x2F;'
};

// Regex containing the keys listed immediately above.
var htmlEscaper = /[&<>"'\/]/g;

// Escape a string for HTML interpolation.
_.escape = function(string) {
  return ('' + string).replace(htmlEscaper, function(match) {
    return htmlEscapes[match];
  });
};

这与Prototype的方法几乎相同。我最近做的大多数JavaScript都有可用的Underscore,所以这些天我倾向于使用_.escape

答案 1 :(得分:11)

无法保证html()将被完全转义,因此连接后结果可能不安全。

html()基于innerHTML,浏览器可以在不违反许多期望的情况下实施innerHTML,以便$("<i></i>").text("1 <").html()"1 <",并且$("<i></i>").text("b>").html()"b>"

然后,如果你连接这两个单独安全的结果,你会得到"1 <b>",这显然不是两个明文片段串联的HTML版本。

因此,从第一原则中推导出这种方法并不安全,并且没有广泛遵循的innerHTML规范(尽管HTML5确实解决了这个问题)。

检查它是否符合您要求的最佳方法是测试这样的角落情况。

答案 2 :(得分:1)

那应该有用。这基本上是Prototype.js库如何做到的,或者至少它是如何做到的。我通常会在三次调用“.replace()”时这样做,但这主要只是一种习惯。