Skip to content

CSRF(Cross-site request forgery), 即跨站请求伪造,指的是黑客诱导用户点击链接,打开黑客的网站,然后黑客利用用户目前的登录状态发起跨站请求

  • 自动发送 get 请求
  • 自动发送 post 请求
  • 诱导点击发送 get 请求

<!--more-->

自动发送 get 请求

html
<img src="https://xxx.com/info?user=hhh&count=100"></img>

进入页面后自动发送 get 请求,值得注意的是,这个请求会自动带上关于 xxx.com 的 cookie 信息(这里是假定你已经在 xxx.com 中登录过)。

假如服务器端没有相应的验证机制,它可能认为发请求的是一个正常的用户,因为携带了相应的 cookie,然后进行相应的各种操作,可以是转账汇款以及其他的恶意操作。

自动发送 post 请求

黑客可能自己填了一个表单,写了一段自动提交的脚本

html
<form id="hacker-form" action="https://xxx.com/info" method="POST">
  <input type="hidden" name="user" value="hhh" />
  <input type="hidden" name="count" value="100" />
</form>
<script>
  document.getElementById("hacker-form").submit();
</script>

同样也会携带相应的用户 cookie 信息,让服务器误以为是一个正常的用户在操作,让各种恶意的操作变为可能。

诱导用户点击发送 get 请求

在黑客的网站上,可能会放上一个链接,驱使你来点击

小结

这就是 CSRF 攻击的原理。和 XSS 攻击对比,CSRF 攻击并不需要将恶意代码注入用户当前页面的 html 文档中,而是跳转到新的页面,利用服务器的验证漏洞和用户之前的登录状态来模拟用户进行操作

防范措施

CSRF 攻击中重要的一环就是自动发送目标站点下的 Cookie,然后就是这一份 Cookie 模拟了用户的身份。因此在 Cookie 上面下文章是防范的不二之选。

恰好,在 Cookie 当中有一个关键的字段,可以对请求中 Cookie 的携带作一些限制,这个字段就是 SameSite。

SameSite 可以设置为三个值,Strict、Lax 和 None。

a. 在 Strict 模式下,浏览器完全禁止第三方请求携带 Cookie。比如请求 shenzjd.com 网站只能在 shenzjd.com 域名当中请求才能携带 Cookie,在其他网站请求都不能。

b. 在 Lax 模式,就宽松一点了,但是只能在 get 方法提交表单况或者 a 标签发送 get 请求的情况下可以携带 Cookie,其他情况均不能。

c. 在 None 模式下,也就是默认模式,请求会自动携带上 Cookie

验证来源站点

这就需要要用到请求头中的两个字段: Origin 和 Referer。

其中,Origin 只包含域名信息,而 Referer 包含了具体的 URL 路径。

当然,这两者都是可以伪造的,通过 Ajax 中自定义请求头即可,安全性略差

CSRF Token

浏览器向服务器发送请求时,服务器生成一个字符串,将其植入到返回的页面中。然后浏览器如果要发送请求,就必须带上这个字符串,然后服务器来验证是否合法,如果不合法则不予响应。这个字符串也就是 CSRF Token,通常第三方站点无法拿到这个 token, 因此也就是被服务器给拒绝

Django 作为 Python 的一门后端框架,用它开发过的同学就知道,在它的模板(template)中, 开发表单时,经常会附上这样一行代码:

python
{% csrf_token %}

总结

CSRF(Cross-site request forgery), 即跨站请求伪造,指的是黑客诱导用户点击链接,打开黑客的网站,然后黑客利用用户目前的登录状态发起跨站请求

CSRF 攻击一般会有三种方式:

  • 自动 GET 请求
  • 自动 POST 请求
  • 诱导点击发送 GET 请求。

防范措施: 利用 Cookie 的 SameSite 属性、验证来源站点和 CSRF Token

参考链接