前言php
平时不多关注安全这块的技术,曾经也买过一本《Web前端黑客技术揭秘》但至今还没翻过,尴尬。今天的早读文章由腾讯优测@小吉带来的分享。html
正文从这开始~前端
最近深刻了解了一下XSS攻击。之前总浮浅的认为XSS防护仅仅只是输入过滤可能形成的XSS而已。然而这池子水深的很呐。java
XSS的类型node
整体来讲,XSS分三类,存储型XSS、反射型XSS、DOM-XSS。react
存储型XSSjquery
数据库中存有的存在XSS攻击的数据,返回给客户端。若数据未通过任何转义。被浏览器渲染。就可能致使XSS攻击;数据库
反射型XSSjson
将用户输入的存在XSS攻击的数据,发送给后台,后台并未对数据进行存储,也未通过任何过滤,直接返回给客户端。被浏览器渲染。就可能致使XSS攻击;后端
DOM-XSS
纯粹发生在客户端的XSS攻击,好比:http://www.some.site/page.html?default=French
页面代码:
该XSS攻击实现条件:
用户点击了以下链接:
http://www.some.site/page.html?default=<script>alert(document.cookie)</script>
后台对URL参数未作任何过滤处理,返回给客户端,前端直接从url上获取参数。
打开网址的浏览器是低版本浏览器,常见ie8如下
知足以上三者,就会致使URL上的js代码执行:alert(document.cookie),可是攻击者能够利用这个,作你没法想象的事情。在现代浏览器中,已经作了xss过滤,一旦检测到xss,会提示报错以下:
以上即是学术上的划分的XSS攻击类型,二、3类型其实都是反射型的攻击。了解了这些,意识到XSS攻击无处不在啊。那么如何对XSS进行防护?从输入到输出都须要过滤、转义。
XSS防护—输入输出的过滤和数据转义
输入
客户端求情参数:包括用户输入,url参数、post参数。
在产品形态上,针对不一样输入类型,对输入作变量类型限制。
如,http://xss.qq.com?default=12,Default值强制限制为整形。
咱们的后台是node,使用joi对于输入作类型限制:
字符串类型的数据,须要针对<、>、/、’、”、&五个字符进行实体化转义。
输出
即便在客户端对用户的输入作了过滤、转义,攻击者同样可能,经过截包,转发等手段,修改你的请求包体。最终仍是要在数据输出的时候作数据转义。
好啦,到数据转义啦,不就是对<>,'&"这些字符作实体化转义吗?若是你认为这么简单,NO NO NO…由于浏览器解析中html和js编码不同,以及上下文场景多样,因此对于后台输出的变量,不一样的上下文中渲染后端变量,转码不同。
下面的HTML片断显示了如何安全地在多种不一样的上下文中渲染不可信数据。
状况一
数据类型:String
上下文:HTML Body
示例代码:<span>UNTRUSTED DATA</span>
防护措施:HTML Entity编码
状况二
数据类型:String
上下文:安全HTML变量
示例代码:<input type="text" name="fname" value="UNTRUSTED DATA">
防护措施
1. HTML Attribute编码
2. 只把不可信数据放在安全白名单内的变量上(白名单在下文列出)
3. 严格地校验不安全变量,如background、id和name
状况三
数据类型:String
上下文:GET参数
示例代码:<a href="/site/search?value=UNTRUSTED DATA">clickme</a>
防护措施:URL编码
状况四
数据类型:String
上下文:使用在src或href变量上的不可信URLs
示例代码:
<a href="UNTRUSTED URL">clickme</a>
<iframe src="UNTRUSTED URL" />
防护措施:
1. 对输入进行规范化
2. URL校验
3. URL安全性认证
4. 只容许使用http和https协议(避免使用JavaScript协议去打开一个新窗口)
5. HTML Attribute编码
状况五
数据类型:String
上下文:CSS值
示例代码:<div style="width: UNTRUSTED DATA;">Selection</div>
防护措施:
1. 使用CSS编码
2. 使用CSS Hex编码
3. 良好的CSS设计
状况六
数据类型:String
上下文:JavaScript变量
示例代码:
<script>var currentValue='UNTRUSTED DATA';</script>
<script>someFunction('UNTRUSTED DATA');</script>
防护措施:
1. 确保全部变量值都被引号括起来
2. 使用JavaScript Hex编码
3. 使用JavaScript Unicode编码
4. 避免使用“反斜杠转译”(\"、\'或者\)
状况七
数据类型:HTML
上下文:HTML Body
示例代码:<div>UNTRUSTED HTML</div>
防护措施:
[HTML校验 (JSoup, AntiSamy, HTML Sanitizer)]
(https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.236_-_Use_an_HTML_Policy_engine_to_validate_or_clean_user-driven_HTML_in_an_outbound_way)
状况八
数据类型:String
上下文:DOM XSS
示例代码:<script>document.write("UNTRUSTED INPUT: " + document.location.hash);<script/>
防护措施:
基于DOM操做的XSS漏洞防护措施
全部输出的数据转义都应该遵照上表的规则,而针对同步数据和异步数据,有较大的使用区别作了区分:
同步数据
React页面主动屏蔽掉XSS,非react则须要对不可信任数据,要进行输出转义。
对于html白名单需求,可使用SanitizeHelper模块提供了一个方法集合来处理非预期的HTML元素。
不一样的使用方式,编码方式不一样,java现成的工具能够用——ESAPI,不一样位置如何转义可参照ESAPI文档,好比属性值转义:
String safe = ESAPI.encoder().encodeForHTMLAttribute(
request.getParameter( "input" ) );
异步、后台直出给js使用的json数据
对于不可信任的json数据。由于json数据可能用到不一样的地方,因此转义能够放在前端js去转义。
参与运算的动态变量,最好转化为对应类型后再运算。如number型.
若是是字符串操做,保证字符串被引号包裹。
不能使用eval ,new fuction,settimeout执行动态字符串,由于这个字符串极可能就是一个xss代码,若是没法避免,那么也要转义以后再参与运算。
输出到页面上的数据必须使用相应方法转义,前端能够考虑寻找js插件处理。目前jquery-encoder,可用于前端json转义。使用方式与ESAPI相似,在须要渲染的时候进行转义。
前端XSS防护方案大体如上,整理了这么多干货内容,做为小前端的我,表示要吸取好几天。
最后,再跟你们分享个实际工做中的案例吧
除了上面的XSS攻击,分享一个让你意想不到的安全漏洞。
在优测项目,早期研发环境中,咱们的测试人员提出了以下的安全漏洞:
以下登陆页面咱们为了用户能在登陆以后访问到以前浏览的页面,因此在url加入了一个service参数,可是未对它作任何校验,可能会被钓鱼网站利用。
该攻击实现条件:
用户点击了以下链接:
https://cas.utest.qq.com/qqlogin?service=http%3A%2F%2Fpianzi.com;
后端未对service参数作校验,这个链接能够正常跳转到上图的页面;
用户输入账号登陆后,跳转到http://pianzi.com;
这是个钓鱼网站,经过网站风格欺骗,对用户进行引导性操做;
用户输入一些有用的信息;
在不知不觉之间,用户泄漏了本身的信息。
好深的套路啊~~研发哥哥赶忙寻找解决办法,最终确认方案为:对登陆后跳转地址采用白名单机制。
对于这个老生长谈的XSS攻击,WEB开发者,只是了解其一,前端出身的孩子,对这方面了解甚少,跟我同样几乎没这方面意识的同窗怕是也有很多。
做为懒人一枚,作什么都想找一个一劳永逸的办法,可是对于XSS攻击,无处不在,没有一个很好的全局处理方案。前端小朋友多了解了解常规的XSS攻击,在码代码的时候有这个防攻击意识,也是极好的。
前端安全还有许多了解的方面,如何预防csrf攻击,启用现代浏览器安全防护等等,都须要去了解。
最后,若是你是前端开发,腾讯优测H5测试绝对是你的开发好助手,提高开发效率那是杠杠滴!有机会你们能够玩玩。