CSRF (Cross Site Request Forgery)
攻击者诱导受害者进⼊入恶意⽹网站,在第三⽅方⽹网站中,向被攻击⽹网站发送跨站请求。利利⽤用受害者 在被攻击⽹网站已经获取的注册凭证,绕过后台的⽤用户验证,达到冒充⽤用户对被攻击的⽹网站执⾏行行 某项操作的⽬目的。
<form action="http://bank.example/withdraw" method=POST> <input type="hidden" name="account" value="lubai" /> <input type="hidden" name="amount" value="10000" /> <input type="hidden" name="for" value="hacker" />
</form>\
<script> document.forms[0].submit(); </script>
<a href="http://bank.example/withdraw?name=xxx&amount=xxxx" taget="_blank"> 错过再等⼀一点!!!快来看看
</a>
如何防范CSRF的攻击呢?
⾸先咱们通过上⾯面的举例例可以知道, CSRF⼀一般都是发⽣生在第三⽅方域名, 攻击者也⽆无法获取到 Cookie信息, 只是可以利利⽤用浏览器器机制去使⽤用Cookie.
所以咱们可以针对这两点来看防范策略略:
阻⽌止第三⽅方域名的访问
-
Cookie SameSite
SameSite有3个值: Strict, Lax和NoneStrict:浏览器器会完全禁⽌止第三⽅方cookie。⽐比如a.com的⻚页⾯面中访问 b.com 的资源,那么 a.com中的cookie不不会被发送到 b.com服务器器,只有从b.com的站点去请求b.com的资源,才 会带上这些Cookie
Lax:在跨站点的情况下,从第三⽅方站点链接打开和从第三⽅方站点提交 Get⽅方式的表单这两种 ⽅方式都会携带Cookie。但如果在第三⽅方站点中使⽤用POST⽅方法或者通过 img、Iframe等标签加 载的URL,这些场景都不不会携带CookieNone:任何情况下都会发送 Cookie数据
-
同源检测
通过检测request header中的origin referer等, 来确定发送请求的站点是否是⾃自⼰己期望中站点.
⽐比如referer, 我们可以在服务端去判断referer是否来⾃自可信域, 同样也可以做⼀一些referer发送时 的设置:
对于同源的链接和引⽤用,会发送Referer,referer值为Host不不带Path;跨域访问则不不携带 Referer。例例如:aaa.com引⽤用bbb.com的资源,不不会发送Referer(服务端在接收到没有referer 的请求时就不不做响应)
这就提到了了Referrer-Policy这个请求头. developer.mozilla.org/zh-CN/docs/… HTTP/Headers/Referrer-Policy, 控制什什么情况下应该携带/不不携带referer
提交请求时附加额外信息
因为攻击者⽆无法通过csrf来获取本域下的cookie等信息, 所以可以利利⽤用这⼀一点来做防范.
-
CSRFToken
⽤用户打开⻚页⾯面的时候, 服务器器利利⽤用加密算法给当前⽤用户⽣生成⼀一个ToKen
每次⻚页⾯面加载时, 前端把获取到的Token加到所有的能发请求的html元素上, ⽐比如form, a 每次前端发起请求, 都携带Token参数
服务端每次接收请求, 都校验Token的有效性. -
双重Cookie
⽤用户访问⽹网站的时候, 服务器器向浏览器器注⼊入⼀一个额外的cookie, 内容随便便, ⽐比如 csrfcookie=lubaixzxfasdfasfew
每次前端发起请求, 都在请求上拼接上csrfcookie这个参数, 参数值就从cookie⾥里里获取 服务端每次收到请求, 就去校验请求参数⾥里里的值和cookie⾥里里的值是否⼀一致但是这种⽅方式安全性不不如CSRF Token. 咱们来看⼀一下原因:
-
如果前端域名和服务端域名不不⼀一样,⽐比如前端fe.a.com,后端rd.a.com,那如果服务端希望前端
能拿到csrfcookie, 就只能把这个cookie设置到a.com域下, 并且不不能设置为http-only
-
那么a.com的每个⼦子域名就都可以获取到这个cookie
-
⼀一旦某个⼦子域名遭到xss攻击,cookie就很容易易被窃取或者被篡改.
-
攻击者利利⽤用篡改或者窃取的csrfcookie,就可以攻击fe.a.com了了