Web安全之CSRF跨站请求伪造攻击
2015-09-02 09:08
495 查看
CSRF全称Cross-Site Request Forgery,跨站请求伪造攻击。
其攻击原理是:
攻击者在用户浏览网页时,利用页面元素(例如img的src),强迫受害者的浏览器向Web应用程序发送一个改变用户信息的请求。
由于发生CSRF攻击后,攻击者是强迫用户向服务器发送请求,所以会造成用户信息被迫修改,更严重者引发蠕虫攻击。
CSRF攻击可以从站外和站内发起。
从站内发起CSRF攻击,需要利用网站本身的业务,比如“自定义头像”功能,恶意用户指定自己的头像URL是一个修改用户信息的链接,当其他已登录用户浏览恶意用户头像时,会自动向这个链接发送修改信息请求。
从站外发送请求,则需要恶意用户在自己的服务器上,放一个自动提交修改个人信息的htm页面,并把页面地址发给受害者用户,受害者用户打开时,会发起一个请求。
如果恶意用户能够知道网站管理后台某项功能的URL,就可以直接攻击管理员,强迫管理员执行恶意用户定义的操作。
一个没有CSRF安全防御的代码如下:
代码中接收用户提交的参数“email,tel,realname”,之后修改了该用户的数据,一旦接收到一个用户发来的请求,就执行修改操作。
提交表单代码:
当用户点提交时,就会触发修改操作。
下面我们说说如何攻击这么一个网站。如果该网站啊alibaba.com的一个部分,那么我们可以构建两个html页面:
1. 第一个页面a.html,其中通过iframe指向b.html,把宽度和高度都设为0:
这是为了当攻击发生时,受害用户看不到提交成功结果页面。
2. 页面b.html中,有一个表单和一段脚本,脚本的作用是,当页面加载时自动提交这个表单:
注意表单的指向是
3. 将a.html放在自己的web服务器上,发送给登录用户即可:
4. 用户打开a.html后,会自动提交表单,发送给alibaba.com下那个存在CSRF漏洞的Web应用,所以用户的信息,就被迫修改了。而且整个攻击过程中,受害者仅仅看到一个空白页面,且不知道自己信息已被修改。
1. 在用户登录时,设置一个随机的TOKEN也就是令牌,同时种植在用户的cookie中,当用户浏览器关闭、或用户再次登录时,清除TOKEN:
植入令牌到cookie中。
2. 在表单中生成一个隐藏域,它的值就是cookie中随机TOKEN:
通过md5加密将客户端cookie中令牌值传递到服务器端。
3. 表单被提交后,就可以判断表单中的TOKEN和用户cookie中的TOKEN是否一致,如果不一致或没有这个值,就是CSRF攻击:
以上就是防御CSRF的基本方法了。那么还有几个问题:
1. 如果表单不是post而是get方式提交呢?
如果用get方式提交,TOKEN会出现在url中,攻击者可以引诱攻击者点击自己的网站,然后从http头部中的referrer 的url来获取TOKEN,再来攻击。
2. 为什么不直接验证referrer?
网站内部也可能出现CSRF攻击,而referrer 只能判断是否来自可信任网站。
3. 如果先发生XSS攻击,攻击者可以拿到用户页面的TOKEN怎么办?
CSRF防御是建立在XSS防御之后的防御,如果XSS防御失效,攻击者可以拿到用户页面所有信息,CSRF当然会失去效果。当然我们还是可以防止这种情况的发生,就是在表单提交的时候要求输入验证码。这样就可以防御啦。
其攻击原理是:
攻击者在用户浏览网页时,利用页面元素(例如img的src),强迫受害者的浏览器向Web应用程序发送一个改变用户信息的请求。
由于发生CSRF攻击后,攻击者是强迫用户向服务器发送请求,所以会造成用户信息被迫修改,更严重者引发蠕虫攻击。
CSRF攻击可以从站外和站内发起。
从站内发起CSRF攻击,需要利用网站本身的业务,比如“自定义头像”功能,恶意用户指定自己的头像URL是一个修改用户信息的链接,当其他已登录用户浏览恶意用户头像时,会自动向这个链接发送修改信息请求。
从站外发送请求,则需要恶意用户在自己的服务器上,放一个自动提交修改个人信息的htm页面,并把页面地址发给受害者用户,受害者用户打开时,会发起一个请求。
如果恶意用户能够知道网站管理后台某项功能的URL,就可以直接攻击管理员,强迫管理员执行恶意用户定义的操作。
攻击
下面我们举个例子。一个没有CSRF安全防御的代码如下:
$userid=$_SESSION["userid"]; $email=$_REQUEST["email"]; $tel=$_REQUEST["tel"]; $realname=$_REQUEST["realname"]; $params = array(); $params[0] =$email; $params[1] = $tel; $params[2] = $realname; $params[3] =$userid; $sql = "update user set email=?,tel=?,realname=? where userid=?"; execUpdate($sql,$params);
代码中接收用户提交的参数“email,tel,realname”,之后修改了该用户的数据,一旦接收到一个用户发来的请求,就执行修改操作。
提交表单代码:
<form action="http://localhost/servlet/modify" method="POST"> <input name="email"> <input name="tel"> <input name="realname"> <input name="userid"> <input type="submit"> </form>
当用户点提交时,就会触发修改操作。
下面我们说说如何攻击这么一个网站。如果该网站啊alibaba.com的一个部分,那么我们可以构建两个html页面:
1. 第一个页面a.html,其中通过iframe指向b.html,把宽度和高度都设为0:
<iframe src="b.htm" width="0" height="0"></frame>
这是为了当攻击发生时,受害用户看不到提交成功结果页面。
2. 页面b.html中,有一个表单和一段脚本,脚本的作用是,当页面加载时自动提交这个表单:
<form id="modify" action="http://alibaba.com/servlet/modify" method="POST"> <input name="email"> <input name="tel"> <input name="realname"> <input name="userid"> <input type="submit"> </form> <script> document.getElementById("modify").submit(); </script>
注意表单的指向是
alibaba.com/servlet/modify
3. 将a.html放在自己的web服务器上,发送给登录用户即可:
4. 用户打开a.html后,会自动提交表单,发送给alibaba.com下那个存在CSRF漏洞的Web应用,所以用户的信息,就被迫修改了。而且整个攻击过程中,受害者仅仅看到一个空白页面,且不知道自己信息已被修改。
防御
有攻击就有防御,要防御CSRF工具,必须遵循以下三步:1. 在用户登录时,设置一个随机的TOKEN也就是令牌,同时种植在用户的cookie中,当用户浏览器关闭、或用户再次登录时,清除TOKEN:
<?php //构造加密的Cookie信息 $value = “DefenseSCRF”; setcookie(”cookie”, $value, time()+3600); ?>
植入令牌到cookie中。
2. 在表单中生成一个隐藏域,它的值就是cookie中随机TOKEN:
<?php $hash = md5($_COOKIE['cookie']); ?> <form action="http://localhost/servlet/modify"method="POST"> <input type=”hidden” name=”hash” value=”<?=$hash;?>”> <input name="email"> <input name="tel"> <input name="realname"> <input name="userid"> <input type="submit"> </form>
通过md5加密将客户端cookie中令牌值传递到服务器端。
3. 表单被提交后,就可以判断表单中的TOKEN和用户cookie中的TOKEN是否一致,如果不一致或没有这个值,就是CSRF攻击:
<?php if(isset($_POST['hash'])) { $hash = md5($_COOKIE['cookie']); if($_POST['hash'] == $hash) { doJob(); } else { //... } } else { //... } ?>
以上就是防御CSRF的基本方法了。那么还有几个问题:
1. 如果表单不是post而是get方式提交呢?
如果用get方式提交,TOKEN会出现在url中,攻击者可以引诱攻击者点击自己的网站,然后从http头部中的referrer 的url来获取TOKEN,再来攻击。
2. 为什么不直接验证referrer?
网站内部也可能出现CSRF攻击,而referrer 只能判断是否来自可信任网站。
3. 如果先发生XSS攻击,攻击者可以拿到用户页面的TOKEN怎么办?
CSRF防御是建立在XSS防御之后的防御,如果XSS防御失效,攻击者可以拿到用户页面所有信息,CSRF当然会失去效果。当然我们还是可以防止这种情况的发生,就是在表单提交的时候要求输入验证码。这样就可以防御啦。
相关文章推荐
- 线程全解
- 使用Clonezilla("再生龙")对Linux系统硬盘进行镜像和克隆
- 深受开发者喜爱的10大Core Data工具和开源库
- GDI+学习笔记2
- UpdateData和PreTranslateMessage函数
- SLURM 安装与配置
- select into from和insert into select from两种表复制语句区别
- ue4和u3d术语对照
- linux 在系统启动过程
- android开源项目学习
- UVA 1610
- PL/SQL与SQL(Oracle)Case语句
- Java基础学习对象、封装第二章实验练习三
- 一种加快在苹果app store中上架的方法
- Error configuring application listener of class org.springframework.web.context.ContextLoaderListene
- CListCtrl 的相关实现方式
- HDU 5305 Friends(dfs)
- 隐写术入门篇——bmp
- HTML头部
- 移动设备的界面