2009-04-23 135 views
17

有时,服务器端会生成嵌入到内嵌JavaScript代码中的字符串。例如,如果“UserName”应该由ASP.NET生成。然后它看起来像。是否需要为javascript字符串“转义”字符“<" and ">”?

<script> 
    var username = "<%UserName%>"; 
</script> 

这是不是安全,因为用户可以有他/她的名字是

</script><script>alert('bug')</script></script>

这是XSS漏洞。

所以,基本上,代码应该是:

<script> 
    var username = "<% JavascriptEncode(UserName)%>"; 
</script> 

JavascriptEncode做什么是添加系统字符 “\” 前 “/” 和 “”“ 和 ”“”所以,输出HTML。就像 VAR的用户名= “</SCRIPT>警报(\ '错误\')</SCRIPT> </SCRIPT>”;

浏览器将不解释“</script>“作为脚本块的结束。所以,XSS避免了。

但是,在那里仍然存在“<”和“>”。建议也要避开这两个字符。首先,我不认为将“<”更改为“& lt”是个好主意和“>”改为“& gt”;这里。而且,我不确定将“<”更改为“\ <”,并且“>”可以被所有浏览器识别。看起来没有必要对“<”和“>”做进一步的编码。

对此有什么建议吗?

谢谢。

回答

16

根据您使用的标记语言,问题有不同的答案。

如果您使用的是HTML,那么您不能用实体来表示它们,因为脚本元素被标记为包含CDATA。

如果您使用的是XHTML,那么您可以使用显式的CDATA标记将它们表示为CDATA,或者您可以使用实体来表示它们。

如果您使用XHTML,但将其作为text/html使用,那么您需要编写符合XHTML规则的东西,但仍然可以使用文本/ html解析器。这通常意味着使用显式的CDATA标记并在JavaScript中注释它们。

<script type="text/javascript"> 
// <![CDATA[ 
    … 
// ]]> 
</script> 

前段时间,我写了一些关于the hows and whys of this的内容。

+1

但是CDATA块内的`]]>`中的`>`必须由`>`重新设置。因此`foo [bar [0]]> 1234`必须替换为`foo [bar [0]] < 1234`或`foo [bar [0]]> 1234`。否则,CDATA块将被过早关闭。 – Gumbo 2009-05-25 21:02:28

+0

由于CDATA呈现&字符的意思是“&”而不是“实体的开始” - 这是行不通的。如果你需要在CDATA中表示字符串“]]>”,那么我很肯定你很勉强,应该使用实体来开始(在CDATA块之外) – Quentin 2009-05-26 06:55:11

+7

或者只是添加一个空格:`foo [bar [0 ]]> 1234` - 或者如果它是字符串的一部分:`'foo [bar [0]]'+'> 1234' - 或者只包含所有脚本在外部.js文件中。 – gnarf 2009-10-02 18:33:58

13

不,您不应该在HTML中使用<script>以内的HTML实体转义<>

  • 使用JavaScript字符串转义规则(更换\\\"\"
  • <\/取代</所有出现,防止逸出<script>元素。

在XHTML中它更复杂。

  • 如果您发送XHTML为XML(与IE不兼容)并且不使用CDATA块,那么除了JavaScript字符串转义之外,您还需要转义实体。
  • 如果您将XHTML作为XML发送并使用CDATA块,则不要转义实体,而应将]]>替换为]]]]><![CDATA[>以防止转义(除JavaScript字符串转义外)。
  • 如果您发送XHTML为text/html(99%的人会这样做),那么您必须一次性使用XML CDATA块,XML CDATA转义和HTML转义。
2

便宜的和容易的方式:

<script type="text/javascript"> 
    var username = "<%= Encode(UserName) %>"; 
</script> 

其中Encode的编码方案是输入的每个字符翻译成相关联的\xABCD表示用JavaScript兼容。

另一种廉价和简单的方法:

<script type="text/javascript"> 
    var username = decodeBase64("<%= EncodeBase64(UserName) %>"); 
</script> 

,如果你只用ASCII处理。

当然,pst用严格的方法来打击头部。

相关问题