使用jQuery转义HTML

Mic*_*ior 37 html javascript jquery escaping

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

$('<i></i>').text(TEXT_TO_ESCAPE).html();
Run Code Online (Sandbox Code Playgroud)

<i>标签仅仅是一个虚拟的jQuery的需要一个容器设置的文本.

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

谢谢!

mu *_*ort 62

这是一个非常标准的做法,我的版本使用了一个<div>:

return $('<div/>').text(t).html();
Run Code Online (Sandbox Code Playgroud)

这在技术上并非100%安全,尽管Mike Samuel指出,但在实践中它可能非常安全.

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

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

但它曾经使用"在div中放置文本并提取HTML"技巧.

还有_.escape在下划线,这不这样说:

// 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];
  });
};
Run Code Online (Sandbox Code Playgroud)

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

  • @Mike:我认为`.text(t).html()`或Prototype的`replace`方法真的很棒,两种方法都有问题.标准JavaScript库中缺少`encodeHTML()`函数是一个巨大的漏洞,而且是一个相当令人惊讶的疏忽. (6认同)
  • 很多图书馆都这样做.请注意,此处的结果可以安全地嵌入PCDATA上下文和RCDATA上下文,但不是属性上下文,因为引号不会被转义.如果你可能容易遭受UTF-7攻击等,你也应该逃避'+':http://en.wikipedia.org/wiki/UTF-7#Security (3认同)
  • @Marcel:但是我们确实有`encodeURIComponent`和JavaScript的根源在Web浏览器中.并且,每个人最终都自己编写的事实表明标准库中存在差距. (3认同)

Mik*_*uel 11

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

html()基于innerHTML和浏览器可以在不违反很多的期待,实现innerHTML$("<i></i>").text("1 <").html()就是"1 <",那$("<i></i>").text("b>").html()"b>".

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

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

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