【翻译】HTML、URL以及Javascript转义

最近被字符转义和XSS的事情搞得焦头烂额,虽然解决了问题却没有一个清晰的认识,google了一下找到了一篇文章觉得不错,正好已经很久没有发文了,翻译一下锻炼锻炼。
原文地址:http://jehiah.cz/a/guide-to-escape-sequences

以下为原文翻译;->

我在过去的十年的Web应用开发中学到了一件事,那就是要想搭建安全的防脚本注入的Web应用很难,真的很难。
问题的关键是太容易忘记在需要的时候去转义字符,偷懒很容易而且也很难发现那些隐蔽的问题场景。在这一点上大多数Web应用框架做的很差或者要花大力气确保把这件事做的正确。

初略的想一下,转义很简单:确保在正确的场景下转义。也就是说你需要总是明确的知道在XHTML下、在URL含有字符以及在处理javascript时如何做正确的转义。不管什么时候你需要输出变量,那么请记得转义。

XHTML转义

大部分时候你构建html文档时都是在服务端的环境下,或者在javascript中当你构建原始html文档时。在这种环境下你需要转义那些能够破坏html开始和结束标签、破坏使用使用引号包围的属性以及破坏html转义符“&”的字符。

为了帮助记忆,想想如何破坏下面这段代码:

<input value="{{value}}">

下面这些字符是需要你转义的

& ==> &amp;
" ==> &quot;
> ==> &gt;
< ==> &lt;
' ==> &#39; (optional)

如果你不是一直使用双引号包围html属性,那么你就应该转义单引号
在pthon中你像下面这样完成转义

xml.sax.saxutils.escape(value, {'"': "&quot;"})

在Javascript中你可以这样做

string.replace('&', "&amp;").replace('"', "&quot;").replace("'", "&#39;")
.replace('>', "&gt;").replace('<', "&lt;")

JAVAScript转义

在Web应用中经常会在<script>标签中输出内容,所以保证输出的内容是经过转义的以避免破坏带引号的字符和</script>标签就变得尤为重要。
为了帮助记忆,想想如何破坏下面这段代码:

<script>    
     var a = "{{value}}";
</script>

典型的我们会将变量进行JSON编码输出到script中

<script>    
     var a = {{json_encode(value)}};
</script>

可不幸的是,这还不够。大部分人听到这个结果都很惊讶包括我自己,一个适当的JSON字符串就能破坏标签
例如:

<script>    
     var a = "</script><script>alert('and now i control your page');</script>";
</script>

注意,你可以在没有双引号的情况下破坏</script>
在使用xml时可以使用PDATA将script整个内容进行html转移但是在xhtml/html这并不是一种选择

解决这个额问题的方法就是用反斜线转移正斜线(注意有一些JSON工具默认这么做的,但有一些不是)
/ > \/ 但是你不能直接这么替换,不然你会将所有的转义反斜线都破坏掉,你可以在进行完JSON编码之后再做如下字符替换 <\/
在python中可以这么做

return json.dumps(value).replace("</", "<\\/>")

URL转义

转义URL看上去非常简单,但实际上也需要一些技巧
同样需要注意的是如果URL在HTML中输出它需要进过html编码。记住如果url包含<,>,”,’,&那就需要在html环境下进行转义
也就是说你需要同时使用Html的&转义和URL%转义

<a href="{{xhtml_escape("http://this.example/" + urllib.quote(value) )}}>...</a>

我可以不遗余力的像你描述空字符和不可打印的字符会出现在你的内容中。你会发现将unicode的0-20号字符转为空格会很有用(译者注:确实是这样,控制符不属于xhtml规范,如果你的内容中含有这样的字符很可能你的页面无法显示),你可以用如下代码完成这个操作:

re.sub(r"[\x00-\x20]+", " ", value)

为了帮助记忆,想想如何破坏下面这段代码:

url = "http://test.example/blog/" + post_name
url = "http://test.example/page?msg=" + message

如果你的变量中含有 #,?,;,&,.,/,%或者任意一种空格,他们都需要用”%“来进行转义
在Javascript中使用encodeURIComponent() (注意:在这种情况下不要使用escape())
在python中是用urllib.quote()或者urllib.urlencode()

<script>    
     var a = "</script><script>alert('and now i control your page');</script>";
</script>

好了,到此就翻译完成了。have fun!!!

Meta

Published: April 12, 2012 Author: ivan Comments:   Word Count: 101
Bookmark and Share

Next: Spring AOP的一些实践

Previous: 利用xl2tpd搭建l2tp VPN服务

Tags

escape javascript python script translate url xss

Article Links

  1. The Definitive Guide to HTML, URL and Javascript Escaping | ...
Comments powered by Disqus