csrf也就是跨站请求伪造(Cross-site request forgery),在看axios文档的时候说它能够抵御csrf攻击,今天来看看什么是csrf攻击,以及如何防护。

什么是csrf

当然网上也有很多讲解什么是csrf的文章,这里简单将讲一下csrf是咋回事:

background Layer 1 网站A 1.登陆网站A 2.登陆成功,本地cookie保存了网站A的登陆凭证 网站B 3.浏览网站B 网站A 4.网站B请求网站A的一个接口, 此时浏览器会带上A网站的cookie去 访问A网站,因为A网站你已经登陆了, 在cookie上已经产生了登陆凭证, 因此就达到了模拟登陆的效果。

上面就是csrf的主要原理,导致csrf的主要问题就是登陆凭证在cookie上,而cookie在请求的时候又会自动带到后端去。

防御csrf的主要原理就是另外增加一个验证的参数,这个参数由后端生成,前端请求参数的时候带上这个参数,然后后端验证这个参数,如果验证通过,说明请求可信任,否则,请求不可信任。

express中配置防御csrf

在express中,有专门处理csrf问题的中间件: csurf,里面有详细的配置,大家可以去看看,现在主要讲解写它的内部逻辑:

它的内部产生两个变量,一个叫csrfSecret,一个叫csrfToken,csrfSecret最先被创建出来(自动创建),可以保存在cookie或者session中。

然后需要手动创建csrfToken,由csrfSecret变成csrfToken需要一个随即的“盐”,名为salt,三者的关系为:csrfToken= salt + '-' + hash(salt + '-' + csrfSecret)。

上面我们说到要防御csrf的话,需要从后端生成一个变量,这个变量就是上面说的csrfToken,然后这个变量会被传递到前端,前端请求的时候带回去,csrfToken中第一个'-'的前面部分是salt,然后和保存好的csrfSecret一起验证这个csrfToken是否有效。

上面就是csurf中间件的主要逻辑了,下面来看看里面的一些具体细节:

cookie配置

csurf里面有一个cookie配置,它的意思是说csrfSecret的保存位置,注意,不是csrfToken的位置!

如果cookie:true那么你需要引用cookie-parser中间件,大致如下:

此时,csrfSecret保存在cookie中,默认的key为_csrf,可以通过cookie中的key来改变这个key。

如果cookie:false(默认),那么你需要引用express-session或者cookie-session,大致如下:

此时,csrfSecret保存在req[sessionKey].csrfSecret中,其中sessionKey可以配置。

csrfToken的传递和回收

上面说过csrfToken是手动创建的,它的传递和回收一般有两种方式:

后端通过render方法传递给页面,前端通过参数形式传递给后端:

上面的方法虽然可行,但是每个请求都要加一个隐形参数比较麻烦;还有一种方式是把carfToken放在请求头里面,然后只要控制全局的ajax请求头就好了。

axios中有两个和csrf相关的参数:xsrfCookieName,xsrfHeaderName。刚好就是出把cookie中的key为xsrfCookieName的csrfToken取出来,放在请求头xsrfHeaderName中,这样后端就能通过截取X-XSRF-TOKEN请求头得到csrfToken了。

一般cookie:true的时候,是通过设置请求头的方式来传递/回收csrfToken;若cooke:false,则一般是通过参数来传递/回收csrfToken的。

csurf中的value(req)

这个方法是用来获取csrfToken的,我们可以看到它会通过哪些来获取:

req.body._csrf

req.query._csrf

req.headers['csrf-token']

req.headers['xsrf-token']

req.headers['x-csrf-token']

req.headers['x-xsrf-token']

我们可以看到,前面两个是为参数传递/回收csrfToken准备的,后面四个是为在请求头传递/回收csrfToken的。

其他文章

0
我要评论

评论

返回
×

我要评论

回复:

昵称:(昵称不超过20个字)

图片:

提交
还可以输入500个字