前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >和XSS漏洞对抗的日子

和XSS漏洞对抗的日子

原创
作者头像
MarsBoy
发布2018-06-19 11:55:26
1.2K1
发布2018-06-19 11:55:26
举报
文章被收录于专栏:前端安全前端安全

| 导语        前端安全日益受到业内的关注,最近笔者和团队在和XSS漏洞对抗的这段时间,总结了部分常见的漏洞和修复方法,下面将结合具体业务对这些漏洞类型进行分析。并分享给大家。

写在前面

       前端安全日益受到业内的关注,前端安全指发生在浏览器端用户界面的各种安全问题。随着前端技术的发展,Web安全早已经从后端波及到前端,并且前端攻击的手段越来越刁钻,前端攻击可以说是“借刀杀人”,因为前端攻击的发生都是在用户的操作下进行的,这里的刀就是用户之手。目前排在前端攻击手段前三位的是:XSS、CSRF、界面伪造(钓鱼)。其中XSS攻击最频繁,XSS发生的多样性导致XSS的漏洞最容易被黑客发现并利用。

       如果有漏洞,并被黑客利用的话,影响面是很广的。近期,笔者就在和XSS漏洞打交道。在和XSS漏洞对抗的这段时间,我们也总结了部分常见的漏洞和修复方法,下面将结合具体场景对这些漏洞类型进行分析。并分享给大家。

1.cookie的正则匹配

       在前端获取本域名下的cookie方式,都是通过document.cookie获取原始cookie串,然后再进行分析和匹配。原始cookie串长成这样:

name1=value1; name2=value2; name3=value3; name4=value4

       第一个name前面没有空格,最后一个value后面没有分号,其余中间的cookie都是name前面有空格,value后面有分号。所以导致匹配cookie串的时候千奇百怪。其中有这样一种匹配方式:

var reg1=new RegExp("(^|\\s)"+name+"=([^;]*)(;|$)");

       设有cookie串:sCookie1为cat=1; dog=2; pig=3

       设有cookie串:sCookie2为xss=2 cat=5; pig=4; cat=1

       现在要获取cat的cookie值,那么reg1在匹配sCookie1的时候是正确的,能得到cat=1,但是在匹配sCookie2的时候,却得到的是cat=5。

       分析原因不难看出,xss的cookie值为2 cat=5,2后面的\scat=5正好符合reg1的正则形式,漏洞在于name前面的正则不严谨,不应该是简单的^或者空格,更加严格的是;\s或者^,即空格前面必须有分号。

       修复之后的正确匹配方式应该是:

var reg2=new RegExp("(^|;\\s*)"+name+"=([^;]*)(;|$)");

【后记】

       正常情况下cookie值很少有形如a=b的形式,但是a=b的形式确实是可以成为cookie值的,所以,黑客可以通过篡改cookie值的方式来达到植入恶意代码的目的。

2.sUrl跳转

       前端业务中,有一种页面是专门做跳转中转的,一般这种页面的url上会带一个目标跳转的链接参数,比如为sUrl,然后页面会做一些统一鉴权类的操作,当需要跳转的时候,直接就跳转到sUrl指定的地址。

       首先科普一下,前端实现页面跳转不严格的来说有三种方法:

1)meta标签refresh属性实现

2)a标签href属性实现

3)脚本控制location对象

       严格意义上,可以从脚本执行直接跳转而无需人工操作的有两种1)和3)

       对于meta标签,下面这行代码将直接立刻跳转到qq首页

$("head").append("<meta http-equiv='refresh' content='0,url=http://www.qq.com'>");

       对于location,可以直接把sUrl赋值给href,或者调用replace,assign方法均可实现跳转。

       那么,sUrl跳转怎么实现xss攻击呢,我们知道浏览器的地址栏可以接受各种合法协议的地址,包括标准的http协议,ftp协议,https协议之外,还有诸多形如:thunder://   chrome://   javascript://等多种伪协议,其中javascript:后面的字符串可以直接当作javascript脚本被执行,非常危险。

       下面直接给出处理这种sUrl跳转类逻辑的防XSS攻击的方法的步骤:

1)从url中获取sUrl的值

2)根据业务需要,写正则表达式判断url是否为标准的链接(http,https,ftp等)

3)如果是,则对sUrl进行统一的xss字符串的过滤

4)对过滤后的地址进行跳转。

       参考处理demo如下:

var urlReg=new RegExp("^((http|ftp|https):\\/\\/[\\w\\-_]+(\\.[\\w\\-_]+)+([\\w\\-\\.,@?^=%&amp;:/~\\+#]*[\\w\-\\@?^=%&amp;/~\\+#])?)$",'i');
if(urlReg.test(decodeURIComponent(tool.request("s_url")))){//判断url合法性
   window.location=tool.xss.filter(decodeURIComponent(tool.request("s_url")));
}else{
   throw 'url非法';
}

【后记】

       这个漏洞的原型来源于网站的登录跳转页:/ xx/login.html,这个页面是登录的跳转中转处理页面。影响面非常广泛,一旦黑客恶意引导登录,跳转地址上带有诸如javascipt:alert(docuemnt.cookie)的代码,用户端的cookie瞬间被获取。这是非常可怕的。

3.昵称的显示

       严格意义上说,在防XSS的背景下,写入到页面中的内容都需要经过xss函数的转义过滤后用jquery提供的html方法写入,或者直接用text方法写入,但是如果有一种值包含的html标签必须要用html写入,又需要防止xss过滤,该怎么办呢。

       这种需求是有的,近期笔者就接触到关于获取的微信昵称中会包含emoji表情的情况,如果通过通用的xss过滤函数之后,emoji标签则显示不了,如果不通过xss过滤直接html写入,又存在昵称会被黑客恶意更改造成xss漏洞的风险。

       奇怪的需求出来后,立马引起了我的注意,因为如果既要过滤xss,又要保留emoji的标签。必须要对昵称中的emoji和其它普通字符进行分离,分开处理之后再合并。

       下面给出处理方案:

1)用正则匹配出昵称中所有的emoji标签,放入数组emojiArr

2)用一个不会被转义的字符替换所有的emoji标签,这里建议用固定前缀+时间戳的形式,如:{tag_时间戳}

3)对替换过的字符串进行统一的xss过滤

4)将过滤后的字符串中{tag_时间戳}用emoji标签数组emojiArr替换

5)替换后的字符串可以直接用html写入页面

      笔者提供了一种方法,使用这个方法,开发人员可以如下使用即可将微信昵称安全完美得显示在页面中了:

var nickName=”哇哈哈<span class="emoji emoji1f48b"></span>”;

$("#nickname").html(tool.xss.filterWxNickName(nickName));

【后记】

       在处理具体问题的时候,可以具体对待,类似处理微信昵称的场景应该有不少,但是思想不变,严格写好标签的匹配正则,然后分离标签和其它字符,再对其它字符进行转义,最后进行合并是通用的处理思想。

前端安全一直是我们追求的目标,我相信在以后的日子里我们还会遇到各种形形色色的前端威胁,但是只要我们有信心和能力与之做斗争,我们的安全网就会越来密,安全性就会越来越高。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写在前面
    • 1.cookie的正则匹配
      • 2.sUrl跳转
        • 3.昵称的显示
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档