XSS的本质和防御

 

    01.XSS的本质

    XSS是什么? 跨站脚本攻击,英文全称是Cross Site Script,为和层叠样式表区分,在安全领域称为XSS.发展到今天,由于JavaScript的强大功能和网站前端应用的复杂化,是否跨域已不再重要.

    XSS的表现? XSS攻击,通常指黑客通过'脚本注入'篡改了网页,插入了恶意的脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击.业界的共识:针对各种不同场景下产生的XSS,需要区别对待.

    XSS本质? XSS的本质是一种HTML注入,用户的数据被当成HTML代码的一部分来执行,从而混淆了原本的语义,产生了新的语义.

    XSS发生? 如果网站使用MVC架构,那么XSS就发生在VIEW,即在应用拼接变量到HTML页面时产生.在有用户提交数据进行输入检查的方法,其实并不是在真正发生攻击的地方防御.

 

    02.XSS的种类

    第一种:反射型XSS

    反射型XSS只是简单地把用户输入的数据"反射"给浏览器.黑客往往诱使用户点击个恶意连接,才能攻击成功.反射性XSS又称非持久性XSS攻击,它存在的时间比较短.在某个文本输入框输入JavaScript代码,用户点击才能生效:<script>alert(/xss/)</script>

    第二种:存储型XSS

    存储型XSS会把用户输入的数据存储在服务器端,这种XSS攻击具有很强的稳定型.常见的场景:黑客写段有恶意的JavaScript代码的博客文章,发表后,所有访问该博客文章的用户,都会在他们的浏览器中执行这段恶意的JavaScript代码.黑客把恶意的脚本保存在服务器端,这种XSS攻击就叫做存储型XSS.存储型XSS做持久型XSS,从效果上来看,它存在的时间比较长,不需要用户操作什么,只要你访问某个网址就会发生.

    第三种:DOM Based XSS

    效果上看是反射型XSS,因为成因特殊,所以单独列出来.通过修改页面的DOM节点形成的XSS,称为DOM Based XSS.

  

    03.XSS的攻击

    黑客能够对用户当前浏览的页面植入恶意脚本,通过恶意脚本,控制用户的浏览器.恶意脚本就是JavaScript脚本.任何JavaScript脚本可以实现的功能,恶意脚本都可以实现.

    案例一:恶意脚本,通过读取浏览器的cookie对象,发起cookie劫持攻击.

    因为cookie中一般加密保存当前用户的登录凭证,cookie如果丢失,意味着用户登录凭证丢失.攻击者可以不通过密码,而直接登录进用户的账户.如何处理这种情况呢?cookie的HttpOnly标识可以防止cookie劫持.

    案例二:攻击者模拟GET,POST请求操作用户的浏览器,通过POST表发发消息等,类似于爬虫来获取你的邮件列表信息.

    两个案例都是在浏览器中通过JavaScript脚本自动进行的,缺少与用户交互过程.如果在提交表单时要求输入验证码,那么一般的恶意脚本都会失效.

    案例三:在大多数修改用户密码的功能中,在提交新密码前,都会要求用户输入旧密码,而旧密码对于攻击者来说是不知道的.这样能限制住XSS攻击吗?答案是否定的.

为了窃取密码,攻击者可以将XSS和钓鱼相结合.实现思路是利用JavaScript在当前页上画出个伪造的登录框,当用户在登录框中输入用户名和密码后,将密码被发送到黑客的服务器上.

    案例四:XSS蠕虫,XSS攻击的终极利用形式,其破坏力和影响力是巨大的.如果是存在存储型XSS,则比较容易发起XSS蠕虫攻击.

如发送站内信,用户留言等页面,都是XSS蠕虫的高发区,需要重点关注.但页面只能由某个用户查看,比如个人材料设置,因为缺少用户间互动,即使存在XSS蠕虫,也不能用于蠕虫的传播.

    攻击者想要使用XSS做坏事是很容易的,XSS蠕虫则能够把破坏无限扩大,这是大型网站需要注意和担心的事情.

 

    04.XSS的危害

    XSS漏洞利用角度看,存储型XSS对攻击者的用处比反射性XSS要大.因为存储型XSS在用户访问正常的URL时会自动触发.而反射性XSS会修改一个正常的URL,一般要求攻击者将XSS URL发送给用户点击,无形中提高了攻击的门槛.

 

    05.XSS的防御

    将主要精力放在如何为网站设计安全的XSS解决方案上.

    5.1 HttpOnly

    服务器端返回请求时处理:HttpOnly解决的是XSS后的cookie劫持攻击.因为浏览器会禁止网页的JavaScript访问带有HttpOnly属性的cookie.即可以对关键性cookie设置HttpOnly属性.需要注意,如果业务复杂,需要在所有set-cookie的位置,给关键性cookie都加上HttpOnly.如有地方漏掉,就可能会导致该方案失效.现在业界给关键业务增加HttpOnly Cookie已经成为标准做法.HttpOnly不是万能的,使用HttpOnly可以有效缓解XSS攻击.

     5.2 输入检查

    输入检查的逻辑,必须放在服务器端代码中实现.

    如果只在客户端进行输入检查,很容易被攻击者绕过去.目前通过的做法是,同时在客户端和服务器端代码中进行相同的输入检查.客户端JavaScript的输入检查,可以阻挡误操作的正常用户,从而节省服务器资源.

    XSS的防御上,输入就检查一般是检查用户输入的数据是否包含一些特殊字符.比如<,>.如果发现存在特殊字符,则需要将这些字符过滤或编码.该输入检查的方式,成为XSS Filter.

在用户提交数据时获取变量,并进行XSS检查.由于数据并没有结合渲染的HTML界面,因此XSS Filter对语境的理解并不完整.

    问题一:可能会放过

    比如<script src="$var"></script>

    其中$var是攻击者可以控制的变量,攻击者只需要提供一个恶意脚本所在的URL地址,即可实施攻击.如果是全局性的XSS Filter,则无法看到用户数据输入的语境,只能看到用户提交的URL,可能会漏报.

    问题二:可能会误杀

    对于敏感字符<,如果XSS Filter不够智能,简单粗暴过滤替换<,可能会改变用户原本的意思.输入的数据,可能被展示在多个地方,每个地方的语境各不相同,如果使用单一替换操作,则会出现很多问题.

过滤器可以做精确的过滤,虽然不能智能分辨业务边界模糊的标签,但可以处理准确清晰,确定无误不允许进入数据库存储的标签内容.比如对<script>标签的过滤.

    5.3 输出检查

    一般来说,除了富文本的输出外,在变量输出到html页面时,可以使用转码或转义的方式来防御XSS攻击.

    安全的编码函数:

    针对html代码编码方式,使用HtmlEncode函数.

    针对JS代码的编码方式,使用JavascriptEncode函数.

    针对XML的编码方式,使用XMLEncode函数.

    'Apache Common Lang'的'StringEscapeUtils'里面,提供很多escape函数.

    需要注意,编码后的数据长度可能会发生变化,而影响某些功能.

   

    06.防御措施

    XSS本质?XSS的本质是一种HTML注入,用户的数据被当成HTML代码的一部分来执行,从而混淆了原本的语义,产生了新的语义.XSS发生在View层,在应用拼接变量到HTML页面时发生.因此用户提交数据进行输入检查的方案,属于不在发生攻击的地方进行防御.

   

    07.风险分析

    从业务风险角度看,XSS攻击的危害:

    .以用户操作来看,存储型XSS的风险会高于反射型XSS,因为存储型XSS会保存在服务器上,可能会跨页面存在.不会改变页面URL的原有结构.

    .以攻击过程来看,反射型XSS,一般要求攻击者诱导用户点击一个包含XSS代码的URL链接.存储型XSS,则只需要让用户查看一个正常的URL链接.比如WEB邮箱的邮件正文存在个存储型的XSS漏洞,当用户打开新邮件时,恶意脚本就会被执行.该隐藏的极其隐蔽,且埋伏在用户的正常业务中,风险很高.

    .从风险角度看,互动交互的页面,可能是发起XSS蠕虫.根据不同页面访问的PV数据,可以分析哪些页面受XSS攻击的影响范围.在修补XSS漏洞最大的挑战: 漏洞数量太多,开发者不愿意来不及修补问题,需要根据重要紧急程度去判断要修复的XSS漏洞.

 

    学习整理自白帽子讲Web安全一书.

原文地址:https://www.cnblogs.com/zhtzyh2012/p/13933165.html