和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 删除。

发表于

我来说两句

1 条评论
登录 后参与评论

相关文章

来自专栏逆向与安全

漏洞分析入门一

0x00: 什么是漏洞及漏洞分类 1. 漏洞是指信息系统在生命周期的各个阶段(设计、实现、运维等过程)中产生的某类问题,这些问题会对系统的安全(机密性、完整性、...

682
来自专栏程序员互动联盟

【编程基础】聊聊如何学习Java——Java的特性

上一篇文章聊了学习编程可能会遇到的心里障碍和为什么学习Java,看了网友们的回复小编很激动,我会积极听取网友们的留言,在我以后的文章中改进。现在说Java语言的...

3529

Eclipse的BIRT:使用Design Engine API

假设您已经在名为“customers”的报告设计文件中将表格定义为报告项目。顾名思义,该表格用于显示示例数据库中的所有客户。此外,它还有一个用于按照国家来对项目...

1292
来自专栏FreeBuf

XSS的原理分析与解剖

作者 Black-Hole 0×01 前言: 《xss攻击手法》一开始在互联网上资料并不多(都是现成的代码,没有从基础的开始),直到刺的《白帽子讲WEB安全》...

1847
来自专栏FreeBuf

Swf Decrypt详解

攻击在持续,攻击的技术在演进。防御者需要持续的跟进研究和投入。最近Flash 0day频繁出现,将我们更多的目光集中到flash上。 Flash作为脚本语言,可...

2557
来自专栏落影的专栏

GPUImage详细解析(八)视频合并混音

回顾 GPUImage源码解析、图片模糊、视频滤镜、视频水印、文字水印和动态图片水印GPUImage的大多数功能已经介绍完毕,这次的demo是源于简书的一位简友...

2885
来自专栏斑斓

面向接口设计与角色接口

问题:在做项目的时候,是不是所有包含非静态方法的类,都要写一个接口?是因为这样的目的是为了解耦,然后通过DI注入实现吗?

671
来自专栏FreeBuf

S2-029 Struts2 标签远程代码执行分析(含POC)

0x00 标签介绍 Struts2标签库提供了主题、模板支持,极大地简化了视图页面的编写,而且,struts2的主题、模板都提供了很好的扩展性。实现了更好的代码...

2208
来自专栏腾讯移动品质中心TMQ的专栏

像 google 一样测试系列之四:技术篇

Android 白盒测试覆盖率低的最主要原因,是大部分人都没有测到 Android 层,只测试了Java层部分,导致覆盖率低。亲,你是不是认为Android层的...

2041
来自专栏个人随笔

Java核心技术(Java白皮书)卷Ⅰ 第一章 Java程序设计概述

第1章 Java程序设计概述 1.1 Java程序设计平台  具有令人赏心悦目的语法和易于理解的语言,与其他许多优秀语言一样,Java满足这些要求.  可移植...

26210

扫码关注云+社区