【问题标题】:How to unescape html in javascript? [duplicate]如何在javascript中取消转义html? [复制]
【发布时间】:2010-11-08 13:41:33
【问题描述】:

我正在使用一个 Web 服务,它会给我以下值:

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

我需要用javascript打印这个看起来像“

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

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

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

(对于那些试图理解我在用 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>

【问题讨论】:

标签: javascript html escaping


【解决方案1】:

尝试 Javascript 中可用的转义和取消转义函数

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

【讨论】:

  • 我告诉我,使用该方法对 html 进行转义可能会导致一些严重的安全问题......这就是我的观点......
  • 没问题,我是在你回答后才做的……不要给这个人投反对票!
  • Escape 和 unescape 函数现已弃用。例如,请参阅this blog entry 了解详细信息。
【解决方案2】:

一些猜测它的价值。

innerHTML 字面意思是解释 hte html 的浏览器。

所以

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

这是 innerHTML 的另一种安全方式,未转义的字符串正在变成 html,因此它没有运行 javascript 的风险。

【讨论】:

    【解决方案3】:

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

    试一试

    "<script>"
    

    然后它重新转义到:

    "&lt;script&gt;"
    

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

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

    【讨论】:

    • 虽然,我不能让它对&amp;lt;script&amp;gt;alert('hi');&amp;lt;/script&amp;gt; 做任何坏事——出于某种原因,虽然脚本已插入,但它并没有运行。但是图像的加载是,所以我利用它来代替......
    • @Stobor - 你能告诉我你的意思吗?我很好奇……
    • @Jeff:已经有一段时间了,但我才看到你的问题。我的意思是我无法让此页面上的脚本运行:jsbin.com/onezo - 虽然查看计算源会显示脚本标签,但它不会 alert()... 不过,我的答案中的警报有效。
    【解决方案4】:

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

    查看http://jsbin.com/uveme/139/ 的示例(基于您的示例,使用原型进行转义。)尝试单击四个不同的按钮以查看不同的效果。只有最后一个是安全风险。 (您可以在 http://jsbin.com/uveme/139/edit 查看/编辑源代码)该示例实际上并没有窃取您的 cookie...

    1. 如果您的文本来自已知安全的来源并且不是基于任何用户输入,那么您是安全的。
    2. 如果您使用createTextNode 创建一个文本节点并使用appendChild 将该未更改的节点对象直接插入到您的文档中,您是安全的。李>
    3. 否则,您需要采取适当的措施来确保不安全的内容无法进入查看者的浏览器。

    注意:As pointed out by Ben Vinegar 使用 createTextNode 不是灵丹妙药:使用它来转义字符串,然后使用 textContentinnerHTML 将转义的文本取出并用它做其他事情并不能保护你在您以后的使用中。特别是,escapeHtml method in Peter Brown's answer below 如果用于填充属性是不安全的。

    【讨论】:

    • 这真的很有用。所以,归根结底,如果有来自用户的任何东西,它应该是 TextNode??
    • @DFectuoso:这是一种方法,如果您不希望他们能够使用任何 HTML 功能,则该方法有效。例如,如果您希望他们为其文本设置样式,则必须弄清楚如何安全地做到这一点......
    • 对安全问题的有趣见解。
    • If you are using createTextNode, you are safe :否,根据benv.ca/2012/10/2/you-are-probably-misusing-DOM-text-methods
    • @buffer:Ben 断章取义地引用了我的回答,这有点偷偷摸摸。但是,他在其他方面是正确的:使用createTextNode 构建escapeHtml 函数可能不安全。虽然此页面上的任何答案都没有建议这样做,但我的措辞可能会让其他人觉得网络上其他地方使用 createTextNode 的功能比适当的更安全。我已经对此进行了澄清。
    【解决方案5】:
    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;
    }
    

    【讨论】:

    • 我刚刚发布的答案允许您将实际页面标题(使用 & 或 &)放在主题行中。 ...并且 html 页面的正文将显示在电子邮件的正文中。
    【解决方案6】:

    一个很好的阅读是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>
    

    【讨论】:

    • 在构建用于填充元素属性的escapeHtml 方法的用例中特别不安全。然而,他的观点是:如果你不能 100% 确定你的函数被使用的上下文,你就不能确定这个函数是安全的。在document.getElementById("whereItGoes").appendChild(document.createTextNode(unsafe_str)); 这样的结构中正确使用createTextNode 并不是他要评论的……
    猜你喜欢
    • 2015-05-16
    • 2012-12-20
    • 2011-09-15
    • 2021-07-30
    • 1970-01-01
    • 2014-02-22
    • 1970-01-01
    • 2010-10-27
    • 1970-01-01
    相关资源
    最近更新 更多