说明:

1. 本ID所有文章皆为原创,写文章时没有参考任何文档,推荐参考的link是网络搜索的,不涉及版权。

2. 此文是纯技术文章,如果不幸遇冷,本ID将无限孤独。

3. 技术是没有司界的,能帮助你是我的快乐,如果不想偷着乐,可以站出来乐一下。

4. 理解了本文,我相信您就打下了可以解决任何复杂的XSS问题的基础,到今天为止才正式说到XSS的核心问题不是卖官子,而是以我的经验深知如何一步一步让人理解它。

5. 如果您真想做专业渗透测试,深入了解了它,你将有能力发现更牛X的XSS问题,甚至知名主流网站上的潜藏的XSS问题。

6. 依然诚请编辑修订,以增加可读性。上篇文章由于涉及到百度的一点小问题(已经火速解决),故声明禁止转载,以避免对其造成不必要的影响,本文您随意。

先说一个关于学习的感受:我本人一直关注“知识”与“知识运用”之间的区别,我曾经举过一个例子说:“知识”与“知识运用”就如牛郎星与织女星,感觉二者之间似乎关系密切,实则相隔甚远!我在初学平面几何时,经常会这么想: 两条线平行则永远不会相交,这不是废话吗! 三角形两边之和当然大于第三边了!…… 在实际运用当中,我经常是需要用它的时候想不起来或者用错了它们。

我的第二篇文章输入验证–避免50%(只是经验值)以上的应用安全攻击,对于此文我相信是IT业界的人都能看明白,但是对于一个企业来说,它的价值万金,有多少人可以体味呢?

对于XSS问题的系统性解决方案上也是一样的。许多公司已经90%以上的程度解决了XSS问题,但是依然存在那10%的风险,风险在哪里,我想我会一步一步给大家分享清楚。XSS问题是全球性普遍性问题,没有深度的探索就不可能有彻底的解决方案,没有灵丹妙药,只有正确的方法!

好,进入正题。

基于HTTP协议的B/S(browser/server)架构的Web应用程序,有它的特殊性,它结构松散、多标签语言相互嵌入以及服务端与客户端使用了相互关联实现上却完全不同等等复杂的技术,以至于给基于HTTP协议的Web应用程序埋下了诸多潜在的安全问题,XSS问题就是其中之一。我们使用C/C++/Javascript,大家都清楚,如果我想在字符串当中表达字符【”】,很自然的就会想到转义【\”】,想在字符串当中表达【\】,就得使用转义(与本文中所说“编码”概念相同)形式【\\】,在HTML文档当中也是这样,但是大家有没有想过这几个问题:

1. 这个转义后的字符串是为谁而转义的?
2. 这个转义后的字符串是何时被还原成转义前的字符串的?
3. 有没有可能还原之后的字符被重新放回到代码中而忽略了转义?

答案:

1. 为解释器(或编译器,为了简单,后面只称解释器)而转义,字符串被解释后在内存当中的字符串等同于转义前字符串

2. 通常解释器是在读取语言(C/C++/Javascript…)字符串后进行本地语言转换前进行还原的

3. 有,在基于HTML架构的前端(浏览器端)应用程序,尤为常见。比如: var myString="<script>alert(\"jiayzhan\")<\/script>"; 这个myString想表达的字符串是

<script>alert("jiayzhan")</script>,如果被document.write(myString)重新写到DOM里,结果是什么呢? 或者也可能会直接赋值给某一HTML节点的innerHTML/outerHTML属性,这里的问题就复杂了,二次赋值之后,你的程序没那么聪明,它不会主动替你转义一下再赋值,你可能会说:这不就是DOM Base XSS吗? 你想的简单了,对于我来说是DOM Based、反射式的还是存储式的,这种分类意义不大,解决方案都是一样,这就是高级别抽象后的解决方案的统一。这个问题较复杂,我们循序渐进的来了解它,您先知道有这么回事儿。有心的读者可能会问:C/C++/Java会有这种情形吗? 答案是:当然有,有一些软件为了兼容性等诸多因素考虑,会在编译时依据条件不同动态生成新的代码然后再进行编译,此时你该如何是好?这不是本文讨论的重点,为了叙述的完整性,提一下有这么回事儿就行。本文的重点是Web应用当中的XSS问题。

铺垫的差不多了,我们来一起看一段以下的HTML的document:

<html>
<body>
<h1>jiayzhan's item</h1>
<a ID="jiayzhan" onclick="alert('jiayzhan\'s onclick')" href="http://www.jiayzhan.org" ">jiayzhan's link</a>
</body>
<script>
location.replace("jiayzhan's URL")
</script>
</html>

【说明】带有字符串【jiayzhan】的一整串,您需要将它们理解为类似于这样的JSP代码:<%=request.getParameter(“jiayzhan”);%>

下面一步一步来说浏览器是如何解码(反转义)的,我就用字符串本身作为位置标识来解释:

1. 位置:jiayzhan’s item, 浏览器在解析这个位置的字符串时,无论如何,会对其进行一次HTML解码,(HTML编码、解码,请参考

2. 位置:jiayzhan\’s onclick,无论如何,浏览器会对其进行:1) 先做HTML解码 2)再做JS解码

3. 位置: http://www.jiayzhan.org,无论如何,浏览器会对其进行:URL解码

4. 位置:jiayzhan’s URL, 无论如何,浏览器会对此位置字符串进行:1)先JavaScript解码 (JS编解码请参考) 2)后URL解码

以上只是一维与二维组合的情形,实际当中还会有三维以上的解码组合,特别是大量使用Web2.0技术的网站。您理解了吗? 如果您真的理解了,请分析一下以下代码段中的变量<%=request.getParameter(“jiyazhan_url”)%>,浏览器如何做解码?如果你真的理解了浏览器的解码过程,你何尝不知道你在解决XSS问题时的编码过程? 请在评论中回复,我会及时与您讨论:

<a href="javascript:backToHome(<%=request.getParameter("jiyazhan_url")%>)" >click jiayzhan</a>

说明:backToHome是一个javascript函数

在这里先不说它的解码过程,提示一下它是一个三维解码过程,供读者讨论吧。

写到这里,我想点睛一下我上文所述的”许多公司已经90%以上的程度解决了XSS问题”而不是100%的原因了。本ID曾给某一知名公司报了一个XSS问题,其存在XSS问题的地方因为是一个三维的解码语法环境,应用安全与开发人员许久也没有找到合理的解决方案,最终此公司删除了那个有XSS问题的功能点。不点名了,如果有幸遇到此公司的应用安全人员,这篇文章读明白了,问题应该就好解决了。还是那句话:知识与知识运用相隔甚远,我无法保证您可以正确运用它。

既然知道浏览器是如何解码的了,我们该如何做编码的事应该水到渠成了,不过依我的经验看,许多专业做XSS问题fix的解决方案的安全人员依然存在难以转过这个弯的情况。下篇文章我将举几个具体的例子来说明如何利用解码原理用来彻底解决XSS问题的编码问题,以及在涉及到多重解码的环境如果考虑维数不足所带来的安全隐患是什么(透露一下:如果编码维数考虑不足的可能结果是:

1). 其实等于没解决,只是漏洞发现的难度大了一些而已,对于我来说都一样 
2). 改变了用户的输入,比如:用户想找一个【“】,结果系统帮它找的是【\"】或【%22】或【&quot;】......)。

今天先这样吧,纯技术文章,不知道有多少同行会耐心的阅读它,我坚信在这个平台上有更多的类似的无保留的分享,才可以共同提高我们应用系统的安全性。请您告诉我关于XSS问题的思考,是否与您想的不一样? 

[原文地址]

相关内容:

XSS解决方案系列之一:淘宝、百度、腾讯的解决方案之瑕疵

XSS解决方案系列之二:知其所以然—浏览器是如是解码的

XSS解决方案系列之三: 例解过后,再回首您正在维护的产品

XSS解决方案系列之四:关于编码

防御XSS的七条原则

相关讨论:

fake 2013-06-03 1楼

输入过滤影响应用性能,lZ怎么看待这个问题的

jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-03

@fake 准确的说本文所述叫:输出过滤。关于性能问题,多虑了,对于一个具有密集输出点的页面,我们做过实验,整体性能影响<5%,多数情况下性能影响都远<5%

无节操 2013-06-03 2楼

期待下篇文章。

jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-03

@无节操 尽量快一些吧

test 2013-06-03 3楼

这篇微博转发很高啊

大佬 2013-06-03 4楼

指望程序员去做这些过滤难度太大了,楼主的方案是?提供一个自己写的过滤函数吗?还是别的?求支招

jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-03

@大佬 有,公司安全策略原因不能提供,我可以给些建议,后文再续吧

大佬 2013-06-03

@jiayzhan 期待也说说解决方案,程序员伤不起

jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-03

@jiayzhan 解决方案会说的,有了原理方案不难了

jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-03

@大佬 解决方案并不能解决谁来fix的问题,理论上必需由程序员来完成,应用安全人员是做solution的。这样对开发人员来说也是一种提升。

Justin (1级) 2013-06-03 5楼

关于那个三维解码的问题,确实不太理解,先HTML再JS再URL?请大神指点一二。。

jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-03

@Justin 恭喜你,你看明白了,呵呵,现实当中还可能会有3维以上情形。多维解码对应的就是多维编码的问题,这就是solution了,只是对于开发来说会有一些困难。

Justin (1级) 2013-06-07

@jiayzhan 多维编码解码的问题,也就是嵌套的问题,如果能搞清楚单一语法环境下顺序,可能也就迎刃而解了。。。在HTML中,不外乎就是DOM和SCRIPT。是不是可以理解成,DOM中的解码一定是HTML第一维,SCRIPT中的解码一定是JS第一维??

jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-08

@Justin 如果<script></script>内的值永远不被涉及到HTML规范中规定的节点中,可以不不做HTML编码。如:在<script></script>调用location.replace()函数,只需URL与JS的组合编码。

s3cj0y 2013-06-03 6楼

也就是说,只需要针对不同的标签使用相应的编码,解码,转义,反转义。把每一维都做好是不是就ok了,求大神指点

jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-03

@s3cj0y 理论上我们解决 XSS问题是不需要手动去解码的,解码是浏览固有机制,我们需要遵循它进行正确的编码就可以。

admin 2013-06-03

@jiayzhan 意思就是解码全交给浏览器去做。期待楼主续作。

robert 2013-06-03 7楼

浏览器最后执行什么,我们就做后解码什么。在一个复杂的业务环境里,确实会有对输出转义,在什么地方转义的问题。

anlfi (1级) ??????????????????????????... 2013-06-03 8楼

好厉害

依稀记得刚接触电脑的时候 说的超文本传输的概念

就是转义 编码 解释器 过滤器 妈妈再也不用担心我学习xss了

其实每一个标签在浏览器的栈 函数都有关系 高级的xss 就是溢出了吧 bypass

什么的都是从汇编调试开始的

或者能直接执行shellcode 做到用户劫持 比如Flash xss第三方也很重要

还有浏览器插件啦 可以说的多了

在浏览器机制方面做好xss安全 其实本质都是User side 问题

只不过现在 Server side也为了User安全进行了一些安全加固吧

求一些绕过浏览器xss防御机制 和标签漏洞调试的文章

其实我什么都不懂的呀 只能乱扯扯 白帽子将web安全我还没看懂呢(吐舌头

jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-03

@anlfi 白帽子讲web安全本ID拜读过,内容多数是黑客思维方式,没有体现出将解决方案作为重点的成分。系统性不错,值得企业应用安全工程师通览一遍。我崇尚的思路是:将问题的root cause表达出来,从root cause上给出解决方案,才是理想的。一个小小的理想主义者~_~

anlfi (1级) ??????????????????????????... 2013-06-03

@jiayzhan

酱紫呀 学习了

Dante (1级) archer & 讨厌复杂的东西 2013-06-04 9楼

最喜欢这个种文章了,目前还不能理解透彻,这阶段时间我也在学习xss,拿个pentesterlab在练习,但是有很多不懂的地方,希望可以获得你的指导。

jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-04

@Dante 有问题可以问,我一有空就回复。

Dante (1级) archer & 讨厌复杂的东西 2013-06-04 10楼

感觉越是猥琐的人,对xss 利用的越有意思,嘎嘎

jeremy 2013-06-04 11楼

关于三维转义,我的理解不知道对不对~

文本需要进行了什么操作就需要进行相关的解码,需要html显示就要html解码,需要在js中使用就要js解码,需要放到url中的就要url解码,

上面那个三维的话,要看backtourl函数里面的操作吧,函数里面用字符串去操作url的时候就用到三维转义了,如果没有操作url就么有(当然函数的字面意思就是操作url了)

jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-04

@jeremy

你的疑问是有效的,此处是假设backToHome就是一个简单的跳转,没有复杂的操作。

此处的href是URL属性,于是浏览器会对其进行URL解码一回。这里需要注意的是:URL/URLComponent的区别,通常URL解码只针对URL本身的合法性与完整性(http://x.y.z)检查, 而URLComponent而是需要对URL当中的参数值进行合法性与完整性检查,这个地方也是开发人员在理解与使用过程当中的容易混淆的地方。

Dante (1级) archer & 讨厌复杂的东西 2013-06-04 12楼

现在在练习xss,/xss/example7.php?name=,这个页面页面对我的输入进行了转义,把我的’<’转了,现在我没有想出办法构建tag来标识js,

<?php require_once '../header.php'; ?>
Hello
<script>
var $a= '<?php echo htmlentities($_GET["name"]); ?>';
</script>
<?php require_once '../footer.php'; ?>

jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-04

@Dante htmlentities函数从字面上看是进行HTML编码的,这明显是用错了,在JS里使用HTML编码要么会有问题,要么改变了用户的输入。我不知道你的目的是什么? 解决问题还是完成攻击?

Dante (1级) archer & 讨厌复杂的东西 2013-06-04

@jiayzhan 点错了,这是pentesterlab的源代码,我只是想做出跨站的效果就好,并且希望知道为什么,

Dante (1级) archer & 讨厌复杂的东西 2013-06-04

@jiayzhan

This example is similar to the one before, however, you won’t be able to use special

characters since they will be HTML encoded. As you will see, you don’t really need

any of these characters.

This issue is common in PHP web application because the well known function

used to HTML-encode character (htmlentities) does not encode single quotes (‘)

unless you told it to using the ENT_QUOTES flag.

这是手册,实话,我看的不是太明白,

Dante (1级) archer & 讨厌复杂的东西 2013-06-04

@jiayzhan 你可以这样理解,如果你是我,现在网站的源文件已经看到,就是刚刚贴的这个,对他进行xss攻击,你会怎么做? 随便学习一下,大牛怎么思考的

jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-04

@jiayzhan 从代码上看貌似没有直接导致XSS问题的地方,但是有隐患,隐患就是这个地方不应该使用HTML编码,这个隐患会在哪里爆发不知道,得看在哪里使用$a及如何使用。

anlfi (1级) ??????????????????????????... 2013-06-04 13楼

请问lz 是程序员吗

厂商

防范

策略

方案

应急响应

听的都想吐了

能不能别那么多专业术语 我已经受不了

一个xss都可以扯这么久 不深入就是赤裸裸的….

———————————————–

好吧我觉得 一个做前端美工的妹子都可以跟我说css hack js hack

xxx风格绕过ie机制来现实某些特殊效果 是多么有意思的事

我已经不再相信hack了 难道你们都是这样的程序员?只是因为这样出现了问题才去找解决方案的研究

我想问你们开心吗 有点hack精神吗 我真没话说了

如有不适请无视 我只是觉得自由比较好哪怕只有我一个人这么想自己研究 也不想去讨论这个

当你的兴趣变成工作 变成一成不变的无数解决方案 生活还有什么意义?

jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-04

@anlfi 呵呵,可爱的妹子,我对前端UI Design很有兴趣,有机会请教你。你说的这些名词我好像极少提及。XSS问题长期困扰着Web应用程序安全性,它确实麻烦,以至于许多公司花了非常大的气力依然无法从根本上解决它,这是我写这些系列的原因与动力。千万别说:一个XSS都可以扯这么久,其实若是想扯的清清楚楚明明白白,还得许久。XSS在owasp排名中基本上没有退出过Top10,如果很简单,它早就消失了。到目前为止它就如Web应用程序的癌症一样始终折磨着web应用。

直觉动物 (1级) 2013-06-07

@anlfi 你的最后一句“当你的兴趣变成工作 变成一成不变的无数解决方案 生活还有什么意义?”这句话真是让我欢喜让我忧!欢喜的是,很庆幸我的兴趣跟工作毫无关系;忧的是,要想工作上有成就,那么感兴趣的工作肯定更容易出成就。

网络安全是我的职业,但是我不喜欢,也不讨厌,我只是本着我能帮助更多人的原则在做事情。可能没有楼主那么牛的技术,但是我能做多少我就做多少。

不管你信不信,这只是我心中所想!

jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-07

@直觉动物 您谦虚了,没有牛与不牛,人人都有知道与不知道的地方,各取所长。

anlfi (1级) ??????????????????????????... 2013-06-08

@直觉动物

你走入了误区 没人逼你做到最好 也没说一定做什么都要有兴趣

就像达芬奇 是建筑师 科学家 军事家 等等等

但是你认为他有吧全部的生活都投入进去吗

这所有的一切都只是生活就像吃饭喝水一样

只是能给你带来惊讶与意外的快乐然而成就只是附带的

假如你把所有时间都投入进去并且十分期望

那么你就会失望而这个就是你的执念也就是你的烦恼

假如你能平静的看待一切

知道到底什么能使自己开心才是最关键的

你到底能做多少其实别并不关心 而是你能做到什么程度

每个人都有自己的长短 你擅长的未必感兴趣 你感兴趣的未必能做到最好就是这样

cnLuu2nd 2013-06-09 14楼

<?php require_once '../header.php'; ?>
Hello
<script>
var $a= '<?php echo htmlentities($_GET["name"]); ?>';
</script>
<?php require_once '../footer.php'; ?>

:

x.php?name=a’;alert(‘x’);var b=’x

lxsec (1级) 2013-06-11

@cnLuu2nd <?php echo htmlentities($_GET["name"], ENT_QUOTES);?>’;

jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-13

@cnLuu2nd 应该增加一些文字说明,尽管我可以猜出部分你的意思,但是我靠猜总归是不靠谱的~_~

lxsec (1级) 2013-06-11 15楼

@jiayzhan 对于您说的位置3 http://www.jiayzhan.org 这个字符串

是只需要URL解码还是需要先HTML再URL

我目前的理解是

将JS 和 HTML 分开来看分别对应JS解码和HTML解码,存在URL再进行URL

如果JS没有对HTML进行DOM操作或者嵌套就视为单独层

如果存在DOM操作或嵌套。那嵌套可以理解成先HTML再JS

那DOM也是这样理解吗?

表述可能不清楚!

jiayzhan (5级) 硅谷某知名IT企业中国区高级应用安全工程师 2013-06-13

@lxsec 你说的没错,先HTML再URL,需要注意的是我所说的URL编码,绝不是JS里的URL参数编码,而只是URL本身http://a.b.c/?a=b&c=d的格式的合法性检查。它的敏感字符集与URL参数编码是不一样的。