本文准备说明以下几个问题:
1. 关于重复编码的问题
2. 关于编码的多种形式的问题
3. 关于编码的几个常见问题
【说明】
本文所述编码是指encode,可以理解为转义,而不是编程序写代码。
编码或者转义机制替我们解决两个问题:
a. 避免保留字冲突问题,对于web应用来说,XSS问题也是其中一类
b. 表达不可输入字符问题,比如我想在程序当中表达一个键盘上没有不可输入的字符,可以通过编码来解决。
【进入正题】
1. 关于重复编码的问题:
我看了一些第三方的decoder/encoder库函数,相当一部分函数是不进行重复编码的,也就是说,当中函数发现【&#】后面带几个数字再带一个【;】号形式时,就不再对其进行HTML编码,同样,对于URL/JS的处理也这样,这肯定是不对的,它违背了浏览器解码的规律,因为浏览器只会在需要解码的地方进行解码而忽略你给它的字符串是什么形式,为何你要在编码的时候去避免重复编码呢?
我知道部分同行不进行重复编码的原因有许多,有的因为使用了一些第三方的库函数,有的是没搞清楚为谁而编码,编码解决的是什么样根本问题……原因列不全,总之在需要重复编码地方你就进行重复编码是没问题的,放心好了。似乎没有例子,总不能让人看着舒心,好吧,举一个小例子:
http://a.b.c/admin.jsp?d=x&e=6 ------redirect-1------->http://a.b.c/login.jsp?backurl_1=http%3A%2F%2Fa.b.c%2Fadmin.jsp%3Fd%3Dx%26e%3D6 ------redirect-2-------> http://a.b.c/sso.jsp?backurl_2=http%3A%2F%2Fa.b.c%2Flogin.jsp%3Fbackurl_1%3Dhttp%253A%252F%252Fa.b.c%252Fadmin.jsp%253Fd%253Dx%2526e%253D6
以上redirect-2后面的URL第一次会返回到redirect-1被解码一次,如果redirect-1到redirect-2没有对backurl_1进行重复编码的话,那么再一次由——redirect-2—–>返回到——redirect-1的时候,就会被解码到原型状态,此时如果backurl_1里的参数值含有URL敏感字符,可能就出问题了。
2. 关于编码的多种形式的问题
看一段敏感字符串: 【</>”&#=-’”】
HTML编码-3: 【&#lt;…..】
JS编码-1: 【\<\/\>\”\&\#\=\-\’\”】
JS编码-2: 【\x3C\x2F\x3E\x22\x26\x23\x3D\x2D\x27\x22】
JS编码-3:【\u003C\u002F\u003E\u0022\u0026\u0023\u003D\u002D\u0027\u0022】
URL编码:【%3C%2F%3E%22%26%23%3D-%27%22%3F】
仔细观察以上编码,值得看一下的是:HTML编码-1:,它的中间位置的数字其实就是当前字符ISO8859-1的编码表示,第二种形式则是基于HTML-1的16进制表示,HTML-3则是别名法表示
对于JS编码,通常对于任何敏感可见字符,你都可以通过【\】+【字符来表达】,所以JS编码-1就是如此,对于-2、-3我觉得也应该一目了然了,与HTML-2都是类似的。
URL编码,应该也不难了吧。
总结一下:浏览器默认会使用ISO8859-1来作为解码的基础,对于HTML/JS/URL只是使用了不同的形式而已,给大家留点问题:
a. 如果Web应用在编程实现时自己指定了字符集,但是却在HTTP Response的Stream里没有指定字符集,会怎么样,浏览器会不会解码出错?
b. 关于编码的问题,是您不好越却不得不越过的一个小砍,望读者下功夫把字符集、编码的历史沿革及不同编码之间的关系搞清楚,许多问题都迎刃而解了。
3. 关于编码的几个常见问题
a. 有时候只使用一种编码尽管不正确,但是似乎是可以解决XSS问题的,为什么还要使用组合编码?
a) 敏感字符集不同,对于HTML来说,可能【?】号不是敏感字符,但是对于URL来说,它是敏感字符
b) 避免改变用户的输入,只有遵循浏览器解码机制,才是完全正确的,否则都会有这样那样的问题
b. URL编码与URL参数编码的问题:
a) 允不允许使用【Javascript:】+ 【javascript函数】类似这样的形式URL的问题是我们进行URL合法性检查的重要部分, 还有ftp://等多种协议
b) 关于URL编码与URL参数的编码,希望你多做实验,找找感觉。我个为认为我们只需要对URL的参数值进行真正意义上的URL编码,而类似于【href】【src】【replace】里一级URL,我们主要是对URL 进行合法性检查,至于为什么,一时半会说不明白,你亲自做实验,效果会更好。
c. 可以重复编码,只要你编码环境没判断错误,重复多少次都没问题。
d. 关于基于JSON数据进行前端复杂的UI绘制的web应用所涉及到的XSS问题,原理完全一致,只是由于语法环境不能一目了然而增加了开发人员判断的难度,但是搞清楚了原理,做对了,在你你fix XSS问题后就不会遇到诸多bug或者fix不彻底的问题
关于XSS问题,至此告一段落,我相信有了这一系列的纲要,虽然不能保证你可以灵活使用,但是至少你有一条明确的路线可以去走。
还引用那句话:“知识”与“知识运用”就如牛郎星与织女星,二者之间似乎关系密切,实则相隔甚远!
相关内容:
相关讨论:
编码 2013-06-18 1楼
hi,有没有专门介绍编码的书籍或者文章啥的?
jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-18
@编码 类似的文章都比较分散,需要自己花时间去总结领会。如果有机会,我可以写一篇,但不要等,因为若想说明白,篇幅会比较长,我一时半会儿未必有时间写出来。
test 2013-06-18 2楼
js escape对于/是不转义的,请问sdl中咋处理
jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-18
@test 你所说的SDL是指?我所了解的与Web应用关系不大,XSS问题主要与Web应用有关,请描述清楚一些你的问题。
zglxw (1级) 2013-06-18 3楼
推荐去看下owasp esapi这个很不错。我准备把sql,xss这样的问题引入esapi来治理。
jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-18
@zglxw 可以使用ESAPI,其实试着去试用它等于带着你去研究一套解决方案的思路,某一天你可能就不想用了,而用自己实现的方式去替代它,并不是ESAPI没有用,它带给你的好处已经带给你了。通用的东西最大的问题就是需要你花诸多功夫去改造它。
zglxw (1级) 2013-06-18 4楼
@jiayzhan 嗯是的。需要一个学习的过程,等熟悉了就可以抽出自己的东东来,但总要这样一个过程。
jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-18 5楼
纠正文中的问题描述,
【原文】
a. 如果Web应用在编码时字符集指自己定了字符集而HTTP Response的Stream里并没有指定字符集,会怎么样,浏览器会不会解码出错?
【修正后】
a. 如果Web应用在编程实现时自己指定了字符集,但是却在HTTP Response的Stream里没有指定字符集,会怎么样,浏览器会不会解码出错?
亮了(2)
FB客服 (3级) FreebuF官方客服 2013-06-18
@jiayzhan 已更新原文。
jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-18
@FB客服 谢谢
anlfi (1级) ??????????????????????????... 2013-06-18 6楼
最后一句 吐下槽吧
"“知识”与“知识运用”就如牛郎星与织女星,二者之间似乎关系密切,实则相隔甚远!"
因为人的天赋不同 虽然知识水平差不多 但其本质是洞察力
比如xss 有些人一眼就能看出来问题在哪
关键在于 你是特殊的洞察出了什么
是怎么利用 还是怎么去修补
前者需要想象力后者需要了解前者的思维
"洞察力,是我们平时所说的创新能力、创意能力、创造能力、想象能力、策略能力的心理基础。"
这才是知识的本质 就是活在当下 即使你知识水平未知
但是你自己仍有一种模式去研究 去洞察 去实践完成这个目标
而不是你到底掌握多少知识 那只是时间问题
真正的活着并不能完全依靠经验 还有你对事物的特殊洞察力 就是不同见解的核心
在“反应”系统中,人对事物的认知,主要来自于以往的“经验”,超出我们“经验”的东西,我们都会无法“反应”,我们要么抵触、要么惊慌失措。从某种角度来看,在“反应”系统中,看到的世界就是我们头脑中“经验”的世界,而非全部真实的世界。
而一个人如果真正能够发现自己的“洞察”模式,并且进入“洞察”模式,那么,这个人就能完全改变自己,甚至是这个人的性格、秉性。因为ta已经不需要“反应”了,ta以往的经验也好、性格也好、秉性也好就不会发挥太多的作用了。
http://www.zreading.cn/archives/2887.html
jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-18
@anlfi 你的知识好渊博,呵呵。有机会向你学习学习“认识”理论。我只学过心理学当中提出的认识理论:意识与潜意识理论,呵呵。
anlfi (1级) ??????????????????????????... 2013-06-18 7楼
"二者之间似乎关系密切,实则相隔甚远!"
那是因为一个是 想象的世界 一个是现实 如果以现实入手就不会存在运用问题了:)
但是你的认知无可避免的会先去了解前人的"经验" 最后变成你可用的资源
实际上你自己并不能真正了解本质
zglxw (1级) 2013-06-18 8楼
@anlfi你哲学学得不错。
perfdark (1级) 2013-06-18 9楼
楼主那个例子的详细步骤是什么?看的不是很懂
我的理解是:
1.访问 http://a.b.c/admin.jsp?d=x&e=6提交数据,转跳
2.到 http://a.b.c/login.jsp?backurl_1=http%3A%2F%2Fa.b.c%2Fadmin.jsp%3Fd%3Dx%26e%3D6
处理,再转跳
3.到 http://a.b.c/sso.jsp?backurl_2=http%3A%2F%2Fa.b.c%2Flogin.jsp%3Fbackurl_1%3Dhttp%253A%252F%252Fa.b.c%252Fadmin.jsp%253Fd%253Dx%2526e%253D6
然后的返回是什么意思??