前提:用户在目标网站的状态被存储在浏览器中,黑客利用该状态取代用户完成敏感操作。
发起 CSRF 攻击的三个必要条件:
第一个,目标站点一定要有 CSRF 漏洞;
第二个,用户要登录过目标站点,并且在浏览器上保持有该站点的登录状态;第三个,需要用户打开一个第三方站点,可以是黑客的站点,也可以是一些论坛。
发送 GET 请求
// 在黑客的页面诱导用户点击图片,发出一个get请求。
// 如果目标服务器足够傻,就能实施一次csrf攻击
<!DOCTYPE html>
<html>
<body>
<h1>黑客的站点:CSRF攻击演示</h1>
<img src="https://time.geekbang.org/sendcoin?user=hacker&number=100">
</body>
</html>
发送 POST 请求
// 在黑客的页面发出一个post请求。
// 如果目标服务器足够傻,就能实施一次csrf攻击
<!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>
要让服务器避免遭受到 CSRF 攻击,通常有以下几种途径。
充分利用好 Cookie 的 SameSite 属性
在 HTTP 响应头中,通过 set-cookie 字段设置 Cookie 时,可以带上 SameSite 选项
set-cookie: 1P_JAR=2019-10-20-06; expires=Tue, 19-Nov-2019 06:36:21 GMT; path=/; domain=.google.com; SameSite=none
SameSite 可以设置为Strict、Lax、None.
验证请求的来源站点
HTTP 请求头中的 Referer 和 Origin 属性
服务器的策略是优先判断 Origin,如果请求头中没有包含 Origin 属性,再根据实际情况判断是否使用 Referer 值。
CSRF Token
第一步,在浏览器向服务器发起请求时,服务器生成一个 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>
网友评论