和XSS漏洞对抗的日子

| 导语        前端安全日益受到业内的关注,最近笔者和团队在和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));

【后记】

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

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

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

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏一个会写诗的程序员的博客

Spring Reactor 项目核心库Reactor Core

Non-Blocking Reactive Streams Foundation for the JVM both implementing a Reactiv...

2142
来自专栏张善友的专栏

LINQ via C# 系列文章

LINQ via C# Recently I am giving a series of talk on LINQ. the name “LINQ via C...

2625
来自专栏张善友的专栏

Mix 10 上的asp.net mvc 2的相关Session

Beyond File | New Company: From Cheesy Sample to Social Platform Scott Hansel...

2537
来自专栏我和未来有约会

Silverlight第三方控件专题

这里我收集整理了目前网上silverlight第三方控件的专题,若果有所遗漏请告知我一下。 名称 简介 截图 telerik 商 RadC...

3985
来自专栏Ceph对象存储方案

Luminous版本PG 分布调优

Luminous版本开始新增的balancer模块在PG分布优化方面效果非常明显,操作也非常简便,强烈推荐各位在集群上线之前进行这一操作,能够极大的提升整个集群...

3095
来自专栏落花落雨不落叶

canvas画简单电路图

60311
来自专栏陈仁松博客

ASP.NET Core 'Microsoft.Win32.Registry' 错误修复

今天在发布Asp.net Core应用到Azure的时候出现错误InvalidOperationException: Cannot find compilati...

4818
来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2707
来自专栏闻道于事

js登录滑动验证,不滑动无法登陆

js的判断这里是根据滑块的位置进行判断,应该是用一个flag判断 <%@ page language="java" contentType="text/html...

6718
来自专栏大内老A

The .NET of Tomorrow

Ed Charbeneau(http://developer.telerik.com/featured/the-net-of-tomorrow/) Exciti...

31210

扫码关注云+社区