如何在JavaScript中unescape html?

时间:2009-07-07 02:09:15

标签: javascript html escaping

我正在使用一个Web服务,它将为我提供以下值:

var text = "<<<&&&";

我需要将其打印成“<<<&&&&”用javascript。

但是这里有一个问题:我不能使用内部HTML(我实际上是将这些值发送到创建文本节点的原型库,因此它不会取消我的原始html字符串。如果编辑库不会是选项,你会如何看待这个HTML?

我需要在这里承担真正的交易,这种类型的字符串有什么风险? innerHTML是如何做到的?还有哪些其他选择?

编辑 - 问题不在于使用javascript普通的escape / unescape甚至jQuery / prototype实现它们,而是关于使用任何这些可能带来的安全问题... aka“他们告诉我使用它们是非常不安全的“

(对于那些试图通过innerHTML来解决这个奇怪字符串的问题,请看看这个简单的例子:

<html>
<head>
<title>createTextNode example</title>

<script type="text/javascript">

var text = "&lt;&lt;&lt;&amp;&amp;&amp;";
function addTextNode(){
    var newtext = document.createTextNode(text);
    var para = document.getElementById("p1");
    para.appendChild(newtext);
}
function innerHTMLTest(){
    var para = document.getElementById("p1");
    para.innerHTML = text;
}
</script>
</head>

<body>
<div style="border: 1px solid red">
<p id="p1">First line of paragraph.<br /></p>
</div><br />

<button onclick="addTextNode();">add another textNode.</button>
<button onclick="innerHTMLTest();">test innerHTML.</button>

</body>
</html>

6 个答案:

答案 0 :(得分:11)

将您的测试字符串更改为&lt;b&gt;&lt;&lt;&amp;&amp;&amp;&lt;/b&gt;,以更好地处理风险是什么......(或更好,&lt;img src='http://www.spam.com/ASSETS/0EE75B480E5B450F807117E06219CDA6/spamReg.png' onload='alert(document.cookie);'&gt;用于窃取垃圾邮件)

请参阅http://jsbin.com/uveme/139/上的示例(根据您的示例,使用原型进行取消转换。)尝试单击四个不同的按钮以查看不同的效果。只有最后一个是安全风险。 (您可以在http://jsbin.com/uveme/139/edit查看/编辑来源)示例实际上并没有窃取您的Cookie ...

  1. 如果您的文字来自已知安全的来源且 不是基于任何用户输入 ,那么您就是安全的。
  2. 如果您使用createTextNode创建文本节点 appendChild将未更改的节点对象直接插入文档 ,那么安全
  3. 否则,您需要采取适当措施,确保不安全的内容无法进入您的浏览器浏览器。
  4. 注意:As pointed out by Ben Vinegar使用createTextNode并不是一个神奇的内容:使用它来转义字符串,然后使用textContentinnerHTML来获取转义文本并执行操作使用它的其他东西并不能保护您的后续使用。特别是,如果用于填充属性,escapeHtml method in Peter Brown's answer below是不安全的。

答案 1 :(得分:5)

一个非常好的读物是http://benv.ca/2012/10/4/you-are-probably-misusing-DOM-text-methods/,这解释了为什么使用createTextNode的常规智慧实际上根本不安全。

以上文章中有关风险的代表性例子:

function escapeHtml(str) {
    var div = document.createElement('div');
    div.appendChild(document.createTextNode(str));
    return div.innerHTML;
};

var userWebsite = '" onmouseover="alert(\'derp\')" "';
var profileLink = '<a href="' + escapeHtml(userWebsite) + '">Bob</a>';
var div = document.getElementById('target');
div.innerHtml = profileLink;
// <a href="" onmouseover="alert('derp')" "">Bob</a>

答案 2 :(得分:2)

尝试使用Javascript

中提供的escape和unescape函数

更多详情:http://www.w3schools.com/jsref/jsref_unescape.asp

答案 3 :(得分:2)

对于它的价值有些猜测。

innerHTML实际上是浏览器解释hte html。

所以&lt;变得不那么符号,因为如果你把&lt;在html文档中。

字符串的最大安全风险&amp;是一个eval语句,任何JSON都可能使应用程序不安全。我不是安全专家,但如果字符串仍然是字符串而不是你应该没问题。

这是innerHTML安全的另一种方式,非转义字符串就是成为html的方式,因此没有运行javascript的风险。

答案 4 :(得分:1)

只要您的代码创建文本节点,浏览器就不应该呈现任何有害的内容。实际上,如果使用Firebug或IE Dev Toolbar检查生成的文本节点的源,您将看到浏览器正在重新转义特殊字符。

给它一个

"<script>"

然后它重新逃脱:

"&lt;script&gt;"

有几种类型的节点:元素,文档,文本,属性等

当浏览器将字符串解释为包含脚本时,危险就在于此。 innerHTML属性易受此问题的影响,因为它将指示浏览器创建Element节点,其中一个节点可以是脚本元素,或者具有内联Javascript,例如onmouseover处理程序。创建文本节点可以避免这个问题。

答案 5 :(得分:1)

function mailpage()
{ mail_str =  "mailto:?subject= Check out the " + escape( document.title ); 
      mail_str += "&body=" + escape("I thought you might be interested in the " + document.title + ".\n\n" );
      mail_str += escape("You can view it at " + location.href + ".\n\n");
      location.href = mail_str;
}