一、CSRF攻击概述
1.1 CSRF攻击定义
- 用户浏览器加载恶意网站时,浏览器中的恶意网站页面向另一目标网站自主发起一个恶意HTTP请求,该攻击方式即为CSRF攻击。
1.2 CSRF攻击的本质
- 在CSRF攻击中,攻击者诱使用户的浏览器发起一个恶意请求,本质上是借助用户的凭证,以用户的身份去执行特定的操作。
- 在用户访问攻击者构造的恶意页面时,如果此时浏览器访问第三方站点带上了第三方的Cookie,那么第三方站点会认为这是一个已登录的用户的访问请求,浏览器就可顺利完成请求操作,因此该攻击方式叫做“跨站请求伪造”。
- 在整个攻击过程中,攻击者并没有拿到受害者的身份凭证,也拿不到操作后的返回结果(同源策略),攻击者只是诱使受害者发出了一个特定的请求。
二、CSRF蠕虫
- 实现蠕虫传播需要利用漏洞携带攻击代码自动扩散,如果CSRF漏洞满足以下两个条件,即可实现自动扩散:
- 在应用中发送其他用户课件内容的功能存在CSRF漏洞,比如发私信、发个人动态、发博客等功能。
- 发送的内容中可以嵌入链接,诱使用户点击,从而触发CSRF漏洞。
- 以“发博客功能存在CSRF漏洞”为例,攻击者可以构造恶意页面,内容如下:
<form id="myForm" astion="http://example.com/new_blog" method="POST"><input name="content" value='<a href="http://evil.site/csrf.html">click me</a>'>
</form>
<script>document.getElementById('myForm').submit();
</script>
三、防御CSRF攻击
3.1 不成熟方案
3.1.1 验证码
- CSRF攻击在用户不知情的情况下构造了网络请求,而验证码则强制用户必须与应用进行交互才能完成最终请求,因此在通常情况下,验证码能够很好地遏止CSRF攻击。
- 缺点
- 处于用户体验考虑,网站无法给所有操作都加上验证码,因此,验证码只能作为防御CSRF攻击的一种辅助手段,不能作为最主要的解决方案。
3.1.2 Referrer校验
- 常见的互联网应用,页面与页面之间都有一定的逻辑关系,因此每个正常请求的Referrer会有一定规律,比如在论坛“发帖”的操作,在正常情况下需要先登录到用户后台,或者访问具有发帖功能的页面,在提交“发帖”的表单时,Referrer值必然是发帖表单所在的页面。如果Referrer值不是这个页面,甚至不是发帖网站的域,那么该请求极有可能是CSRF攻击。
- 缺点
- 缺点一:服务器并非在什么时候都能获取到请求头中的Referrer。
- 不少浏览器扩展为了保护个人隐私,常常会限制Referrer的发送;在某些情况下,浏览器本身就不会发送Referrer,比如从HTTPS跳转到HTTP,出于保护HTTPS全链路数据的考虑,浏览器不会发送Referrer到明文的HTTP请求中。
- 如果服务端应用忽略了Referrer为空的情况,对这种请求不做拦截,那么CSRF防御功能将完全失效。
- 缺点二:很多Web应用功能复杂,开发者如果对每个功能都校验完整的Referrer,代码将很难维护。
- 当业务变化导致URL变动时,还得更改其他接口的Referrer校验逻辑,因此大部分校验Referrer的CSRF防御方案都仅仅是校验Referrer中的域名。
- 如果应用内部本身就能发送链接,那么在应用内部就能发起Referrer合法的恶意GET请求,这样还是能够绕过检测Referrer值的方案。
- 缺点一:服务器并非在什么时候都能获取到请求头中的Referrer。
3.1.3 Cookie的SameSite属性
- Cookie的SameSite属性可以控制Cookie在跨站点请求中是否生效。
- 尽管将Cookie的SameSite属性设置为Strict模式能够缓解域外的CSRF攻击,但仍避免不了从域内发起CSRF攻击。
- Cookie的SameSite属性在设计时就不是用于CSRF防御的,其只能在一定程度上缓解CSRF攻击。
3.2 成熟方案
3.2.1 Anti—CSRF Token
- CSRF攻击之所以能成功,其原因是重要操作的所有参数都是可以被攻击者猜到的。如果攻击者能够猜出URL中的所有参数与参数值,就能够成功构造一个伪造的请求;反之,则无法攻击成功。
- Anti—CSRF Token防御方案
- 用户在发起“进行重要操作”的请求时,需要指明一个Token参数值;
- 该Token参数值由服务端使用“足够安全的随机数生成算法”生成并存储在客户端的Cookie或服务端的session中,Token参数值为用户与服务端的共同秘密;
- 如果发送请求时的参数值与Cookie中的Token参数值或session中的Token参数值不相同,那么该请求无效;
- 由此,在用户不知情的情况下,攻击者无法构造出含有正确参数的恶意请求;
- 用户在发起“进行重要操作”的请求时,需要指明一个Token参数值;
- Anti—CSRF Token方案的使用原则
- Token参数值一定要足够随机化;
- 为了使用方便,可以在一个用户的有效绘画周期内都使用同一个Token参数值;
- 在Web应用中执行敏感操作时,应该通过form表单或通过AJAX以POST请求的形式提交;
- 以POST请求提交能提高Token的保密性,因为如果Token出现在某个页面的URL中,则可能会通过Referrer的方式被泄露给其他站点;
四、LabCross-Site Request Forgery Attack Lab
【待更新】