Mark24
浏览器之CSRF攻击
什么时CSRF攻击
CSRF 全称 Cross Site Request Forgery 又称为 “跨站请求伪造”,指黑客引用用户打开黑客的网站,再黑客的网站,利用用户的登录状态发起跨站请求,简单的讲,CSRF就是黑客利用了用户登陆状态,并通过第三方的站点来做一些坏事。
一些例子
1.自动发起GET请求
<!DOCTYPE html>
<html>
<body>
<h1>⿊客的站点:CSRF攻击演示</h1>
<img src="https://time.geekbang.org/sendcoin?user=hacker&number=100">
</body>
</html>
转账接口隐藏在图片里,页面被加载的时候就会对img请求,结果就发起转账了。
2.自动发起POST请求
<!DOCTYPE html>
<html>
<body>
<h1>⿊客的站点:CSRF攻击演示</h1>
<form id='hacker-form' action="https://time.geekbang.org/sendcoin" method=POST>
<input type="hidden" name="user" value="hacker" />
<input type="hidden" name="number" value="100" />
</form>
<script> document.getElementById('hacker-form').submit(); </script>
</body>
</html>
黑客构建了一个隐藏表单,用户打开站点后,表单被自动提交。
3.引诱用户点击链接
<img width=150 src=http://images.xuejuzi.cn/1612/1_161230185104_1.jpg> </img> </div> <div>
<a href="https://time.geekbang.org/sendcoin?user=hacker&number=100" taget="_blank">
点击下载美⼥照⽚
</a>
</div>
用户一旦点击,发起转账。
和XSS不同的是,CSRF攻击不需要将恶意代 码注⼊⽤户的⻚⾯,仅仅是利⽤服务器的漏洞和⽤户的登录状态来实施攻击。
如何防止CSRF攻击
起CSRF攻击的三个必要条件:
- 第⼀个,⽬标站点⼀定要有CSRF漏洞;
- 第⼆个,⽤户要登录过⽬标站点,并且在浏览器上保持有该站点的登录状态;
- 第三个,需要⽤户打开⼀个第三⽅站点,可以是⿊客的站点,也可以是⼀些论坛
免受CSRF攻击有一下几个途径
1.充分利用好Cookie的SameSite属性
这个属性可以实现从第三方站点发起请求的时候禁止Cookie的发送。
SameSite通常有 Strict,Lax,None三个值。
Strict最严格: 浏览器完全禁止第三方Cookie,简单说如果如果你从A的页面访问了B的资源,而B的Cookie设置了SameSite=Strict 那么这些Cookie时不会被送到B的服务器上的。只有你在B的站点请求B的资源,才会带上这些Cookie
Lax相对宽松一点,跨站点的情况下,从第三方站点的链接打开和从第三方的站点提交Get方式和表单,这两种方式会携带Cookie。 但是如果在第三方站点中使用POST方法或者通过 Img,Iframe等标签加载url,这些场景不会携带Cookie
如果是None,任何情况下都会发送Cookie。
2.验证请求来源站点
在服务端验证请求来源的站点。
需要使用HTTP头中 Referer和Origin属性。 虽然可以通过Referer来告诉服务器但是有一些场景不适用,所以也可以不上传Referere值,具体参考 Referer Policy.
服务端请求中 Referer并不是很可靠,因此标准委员会有制定了 Origin属性,一些场合,比如XMLHTTPRequest、Fetch发起跨站请求或者通过POST方法发送请求时,都会带上Origin。
由于安全考虑Origin只携带域名不携带路径。
服务器的策略优先判断Origin 如果没有 再根据情况判断是否用Referer
3. CSRF Token
大致分为两步:
第一步: 浏览器向服务器发起请求,服务器生成一个 CSRF TOKEN, 其实就是一个字符串,然后将字符串植入返回页面中,例如如下例子:
<!DOCTYPE html>
<html>
<body>
<form action="https://time.geekbang.org/sendcoin" method="POST">
<input type="hidden" name="csrf-token" value="nc98P987bcpncYhoadjoiydc9ajDlcn">
<input type="text" name="user">
<input type="text" name="number">
<input type="submit">
</form>
</body>
</html>
第二部:浏览器发起转账请求,那么就会携带上CSRF Token然后服务器会验证是否合法。
第三方网站因为无法获得TOken的值,即使发出了请求也会因为Token错误而被拒绝。