1.1 含义
CSRF(Cross-site Request Forgery,跨站请求伪造),缩写CSRF,也有少数文章称为XSRF,一种利用用户在当前已登录的Web应用程序上执行非本意操作的攻击方法(利用受害者尚未失效的身份认证信息(cookie,会话等),创建恶意伪造的web页面请求,在受害者不知情的情况下向服务器发送请求完成非法操作(转账、改密等))。
简言之,攻击者间接利用受害者合法身份,以其身份发送恶意请求。
1.2 漏洞实质
攻击者通过技术手段欺骗用户的浏览器访问一个曾经认证过的网站,由于带着认证信息被访问的网站认证信息后认为是真正用户操作便执行操作。(简单的身份认证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发起。)
1.3产生原因
CSRF攻击为何可以实施?
其根本原因是从站点B.com向站点A.com发起请求,会把A.com的cookie一同发送过去。这是由于多标签浏览器(chrome,firefox等)共享一个进程造成的。
但是要注意一点,即虽然可以一同把A.com的cookie随请求发送,但并不能在B.com通过javascript获取和操作A.com下的cookie。
https://blog.csdn.net/SailingLee/article/details/84614073
1.4攻击过程
1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
3. 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
4. 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
5. 浏览器在接收到这些攻击性代码后,根据网站 B 的请求,在用户不知情的情况下携带 Cookie 信息,向网站 A 发出请求。网站 A 并不知道该请求其实是由 B 发起的,所以会根据用户 C 的 Cookie 信息以 C 的权限处理该请求,导致来自网站 B 的恶意代码被执行。
1.5攻击实例 CSRF攻击实例
受害者 Bob 在银行有一笔存款,通过对银行的网站发送请求 http://bank.example/withdraw?account=bob&amount=1000000&for=bob2 可以使 Bob 把 1000000 的存款转到 bob2 的账号下。通常情况下,该请求发送到网站后,服务器会先验证该请求是否来自一个合法的 session,并且该 session 的用户 Bob 已经成功登陆。
黑客 Mallory 自己在该银行也有账户,他知道上文中的 URL 可以把钱进行转帐操作。Mallory 可以自己发送一个请求给银行:http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory。但是这个请求来自 Mallory 而非 Bob,他不能通过安全认证,因此该请求不会起作用。
这时,Mallory 想到使用 CSRF 的攻击方式,他先自己做一个网站,在网站中放入如下代码: src=”http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory ”,并且通过广告等诱使 Bob 来访问他的网站。当 Bob 访问该网站时,上述 url 就会从 Bob 的浏览器发向银行,而这个请求会附带 Bob 浏览器中的 cookie 一起发向银行服务器。大多数情况下,该请求会失败,因为他要求 Bob 的认证信息。但是,如果 Bob 当时恰巧刚访问他的银行后不久,他的浏览器与银行网站之间的 session 尚未过期,浏览器的 cookie 之中含有 Bob 的认证信息。这时,悲剧发生了,这个 url 请求就会得到响应,钱将从 Bob 的账号转移到 Mallory 的账号,而 Bob 当时毫不知情。等以后 Bob 发现账户钱少了,即使他去银行查询日志,他也只能发现确实有一个来自于他本人的合法请求转移了资金,没有任何被攻击的痕迹。而 Mallory 则可以拿到钱后逍遥法外。
1.6 CSRF漏洞检测:
检测CSRF漏洞是一项比较繁琐的工作,最简单的方法就是抓取一个正常请求的数据包,去掉Referer字段后再重新提交,如果该提交还有效,那么基本上可以确定存在CSRF漏洞。
随着对CSRF漏洞研究的不断深入,不断涌现出一些专门针对CSRF漏洞进行检测的工具,如CSRFTester,CSRF Request Builder等。
以CSRFTester工具为例,CSRF漏洞检测工具的测试原理如下:使用CSRFTester进行测试时,首先需要抓取我们在浏览器中访问过的所有链接以及所有的表单等信息,然后通过在CSRFTester中修改相应的表单等信息,重新提交,这相当于一次伪造客户端请求。如果修改后的测试请求成功被网站服务器接受,则说明存在CSRF漏洞,当然此款工具也可以被用来进行CSRF攻击。
1.7绕过姿势
出现这种问题原因是站点仅验证了referer字段,且referer校验不严格(如dvwa靶场的csrf中级别)
移除referer字段便可以成功绕过
token-仅算法验证绕过
原因:应用程序不验证CSRF令牌是否绑定到特定账户而仅验证token算法
绕过:payload中编码一个合法有效的token即可,测试方法:
1账户A登录网站进入修改密码页面
2抓包保存token令牌
3注销账户A,登录账户B
4转到密码更改页面并拦截请求
5使用A账户的token令牌代替B账户的
原因:应用程序仅验证每次token令牌是否不同,且长度一致
绕过:可以通过修改令牌的值保持长度相同即可
原因:应用程序仅在token应用程序不为空的情况下检查token(常见)
绕过:抓包删除请求中的token令牌即可
原因:token令牌由静态和动态两部分组成,程序仅验证了静态部分
绕过:删除动态部分,仅用静态部分绕过
原因:生成的token令牌过于简单有规律可循
绕过:探究令牌生成的方式,通过构造令牌进行绕过
1.8防御CSRF攻击:
referer头校验(服务端校验Referer头是否同域传来以此决定是否响应请求,能抵御99%的攻击)
Q&A:
问:Referer不可伪造吗?
答:Referer是浏览器自动带上的,基于认为浏览器没有漏洞前提下无法伪造。
问:Referer校验有啥缺点吗?
答:当今移动端崛起下流行前后端分离,app和web共用一套后端代码,但app不会自动带Referer头,因此app端不好处理
token校验(CSRF之所以能成功是由于所有的用户验证信息都在cookie中,用户点击链接时保存在浏览器中的cookie会像服务器发送请求,因此黑客在完全不知验证信息情况下间接利用用户的cookie通过安全验证,要想防御CSRF,关键在于请求中放入黑客不能伪造的信息,且该信息不存于cookie中。可以在HTTP请求中以参数的形式加入一个随机产生的token,并在服务器端建立一个拦截器来验证token如果请求中没有token或者token内容不正确则拒绝请求。)
Q&A
问:GET和POST请求怎么加入token?
答:对于GET请求,token附在地址之后;对于POST请求在表单中提交一个隐藏的表单,<input type=“hidden” name=“csrftoken” value=“tokenvalue”>
问:”token验证方式万无一失吗?“
答:”现实中一个网站有很多请求,都加入token是很麻烦的,容易存在疏漏,一般在页面加载时通过js遍历dom树对所有a和form标签后加入token,解决大部门请求,但是页面加载生成后的html代码还需要编码时手动添加。第二个是难以保证token本身安全“
Cookie添加Same-Site属性(限制三方cookie,规避CSRF攻击)
Same-Site的三个数值:
Strict(最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie)
Lax(规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外)
None(网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效)
验证码(敏感操作时候用户提交表单中填写一个随机的字符串,可以完全解决CSRF,缺点是易用性不怎么友好)