CSRF(Cross-site request forgery)
跨站请求伪造,由客户端发起,是一种劫持受信任用户向服务器发送非预期请求的攻击方式,与XSS相似,但比XSS更难防范,常与XSS一起配合攻击
原理详解
攻击者盗用了你的身份信息,以你的名义发送恶意请求,对服务器来说这个请求是你发起的,却完成了攻击者所期望的一个操作
漏洞危害
修改用户信息,修改密码,以你的名义发送邮件、发消息、盗取你的账号等
攻击条件
- 用户已登录存在CSRF漏洞的网站
- 用户需要被诱导打开攻击者构造的恶意网站
攻击过程
实体 | 对象 |
---|---|
用户 | User Q |
存在CSRF漏洞的网站 | Web A |
攻击者构造的恶意网站 | Web B |
- User Q打开浏览器,访问受信任网站Web A,并输入用户名和密码请求登录Web A;
- 验证通过,Web A产生Cookie信息并返回给浏览器;
- User Q在未退出Web A之前在同一浏览器打开一个标签页,访问了含恶意代码的网站Web B;
- Web B接收到用户请求后,返回一些攻击性代码,并发出一个请求访问第三方站点Web A;
- 根据Web B在(4)的请求,浏览器接收到攻击性代码,自动携带Cookie访问Web A;
- Web A并不知道该请求其实是由Web B发起的,因为Web A未对请求做合法性验证,存在CSRF漏洞,让Web B的攻击代码有机会执行,所以会根据User Q的Cookie信息处理该请求,导致恶意代码被执行,这样Web B就达到了模拟用户操作的目的
漏洞成因
主:浏览器cookie不过期,不关闭浏览器或退出登录,都会默认为已登录状态
次:对请求合法性验证不严格
漏洞检测
1.抓取正常请求的数据包,如果不存在token验证,去掉请求头中Referer字段再重新提交,如果服务器返回正常页面,基本可以确定存在CSRF漏洞
2.这里也可以用BurpSuite进行检测。
在浏览器里进行抓包,bp右键有一个CSRF PoC功能,自动生成攻击页面,然后这里面其实可以更方便的修改一些参数,最后提交之后发现是否有变化,若有则存在反之没有。
例子:这里用dvwa来当作例子
右键生成CSRF PoC:
然后这里面其实可以更方便的修改一些参数。修改完后点击这个Test in browser
:
copy出来:
然后要粘贴到抓包测试的相同的浏览器中打开,其它的浏览器会无法访问。以下点击提交请求即可:
看到dvwa里提交之后发现有变化,则存在csrf漏洞:
浏览器安全策略
1.同源策略
同源策略规定了不同源的javascript脚本在没有明确授权的情况下,不能读写对象的资源
同源:同协议、同域名、同端口
2.内容安全策略CSP策略
基于同源策略,所有资源需来自同一个源,但是会带来诸多限制,限制了资源必须在同服务器上,所以浏览器允许页面嵌入第三方资源,同时带来的安全问题由CSP机制解决,让服务器决定浏览器能够加载哪些资源,从而限制其任意下载第三方资源。
3.跨域资源共享CORS策略
基于同源策略,浏览器默认不允许XMLHttpRequest对象访问非同一站点下的资源,而CORS机制使我们能安全的跨域访问资源,实现CORS通信的关键是服务器,只要服务器实现了CORS接口,就可以跨源通信。
4.Cookie策略
Session Cookie:临时Cookie,不指定过期时间
Third-party-Cookie:本地Cookie,可指定过期时间
两者的区别在于“Third-party-Cookie”是服务器在set-Cookie时指定了Expire时间,只有到了Expire时间后Cookie才会失效,所以这种Cookie会保存在本地;而Session Cookie没有指定Expire时间,所以浏览器关闭后,Session Cookie就失效了。
如果浏览器从一个域页面加载另一个域的资源,由于安全原因,某些浏览器会阻止Third-party Cookie的发送。
漏洞利用
通过html标签发送合法跨域请求
img标签不受同源策略的限制,使用img标签的src属性产生的跨域请求被浏览器认为是合法请求,诱导用户点击链接产生攻击
<img src="http://www.hack.com?money=1000&from=sam&to=john" />
为什么说CSRF没有获取cookie,却能利用cookie进行攻击?
攻击者的网站虽然是跨域的,但是他构造的链接是源网站的,因为源网站存在CSRF,构造的链接跟源网站同源,所以浏览器自动携带cookie发起访问
DVWA-CSRF
Low Security
Low级别没有做任何预防CSRF的机制
构造攻击页面,并诱骗受害者访问达到修改密码的目的
<!DOCTYPE html>
<html>
<head>
<title>CSRF</title>
</head>
<img src="http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=hack&password_conf=hack&Change=Change#" border="0" style="display:none;"/>
<h1>404<h1>
<h2>file not found.<h2>
<body>
</body>
</html>
访问此页面后,用户误认为点击了一个404页面,其实密码已修改为hack
- Medium Security
Medium级别对Referer字段做了校验,检查referer是否与主机名SERVER_NAME一致,使用stripos函数从referer字段里查找主机名,如果找到则可以修改密码
<?php
if( isset( $_GET[ 'Change' ] ) ) {
// Checks to see where the request came from
if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false ) {
......
......
?>
只需要在Low级别基础上把攻击页面命名为127.0.0.1.html再访问链接即可修改密码
http://127.0.0.1/dvwa/127.0.0.1.html
- High Security(结合XSS攻击)
High级别验证了token,而token令牌为随机值,无法猜解
<?php
if( isset( $_GET[ 'Change' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
......
......
// Generate Anti-CSRF token
generateSessionToken();
?>
要绕过token验证,关键要获取到token值,在本地环境可以实现High级别CSRF,在实战环境涉及到跨域问题,域名不同,浏览器不允许跨域请求,由于跨域是不能实现的,所以我们要将攻击代码注入到目标服务器中,才有可能完成攻击。
csrf漏洞的防御
CSRF的防御可以从两个方面考虑,一个是后台接口层做防御;另一个则是在前端做防御,这种不同源的请求,不可以带cookie。
前端防御
1.设置cookie的same-site属性:
谷歌提出了same-site cookies概念,same-site cookies 是基于 Chrome 和 Mozilla 开发者花了三年多时间制定的 IETF 标准。它是在原有的Cookie中,新添加了一个SameSite属性,它标识着在非同源的请求中,是否可以带上Cookie,它可以设置为3个值,分别为:Strict、Lax、None。
Strict是最严格的,它完全禁止在跨站情况下,发送Cookie。只有在自己的网站内部发送请求,才会带上Cookie。不过这个规则过于严格,会影响用户的体验。比如在一个网站中有一个链接,这个链接连接到了GitHub上,由于SameSite设置为Strict,跳转到GitHub后,GitHub总是未登录状态。
Lax的规则稍稍放宽了些,大部分跨站的请求也不会带上Cookie,但是一些导航的Get请求会带上Cookie。
None就是关闭SameSite属性,所有的情况下都发送Cookie。不过SameSite设置None,还要同时设置Cookie的Secure属性,否则是不生效的。
更加具体详细的内容请看这里:CSRF(跨站请求伪造)与Cookie的SameSite属性(跨站请求伪造已死)
后端防御
1.验证HTTP Referer字段
referer字段表明了请求来源,通过在服务器端添加对请求头字段的验证拒绝一切跨站请求,但是请求头可以绕过,XHR对象通过setRequestHeader方法可以伪造请求头
2.添加token验证
(这种方式是在表单页面生成一个随机数,这个随机数一定要后端生成,并且对这个随机数进行存储。)客户端令牌token通常作为一种身份标识,由服务器端生成的一串字符串,当第一次登录后,服务器生成一个token返回给客户端,以后客户端只需带上token来请求数据即可,无需再次带上用户名和密码。如果来自浏览器请求中的token值与服务器发送给用户的token不匹配,或者请求中token不存在,则拒绝该请求,使用token验证可以有效防止CSRF攻击,但增加了后端数据处理的工作量
3.验证码
发送请求前需要输入基于服务端判断的验证码,机制与token类似,验证码强制用户与web完成交互后才能实现正常请求,最简洁而有效的方法,但影响用户体验
总结
关于CSRF漏洞有太多分支,包括浏览器安全策略的内部机制原理,CSRF配合XSS攻击方法,CSRF与XSS的区别,跨域解决方案,CORS(跨域资源共享)漏洞,JSONP劫持漏洞等等