上一篇文章讲完了XSS,那么我们接下来要说的就是CSRF。CSRF也是前端安全需要注意的一个重要的环节。
what
CSRF,跨站请求伪造(Cross Site Request Forgery)
简单来说,我是A,其他站点比如B,假装是A做来某件事情。
how
那么,请求是怎么伪造的呢?我们来看下面这张图。
网站A:用户登录,设置登录信息到A的cookie
网站B:诱导用户打开网站B
网站B:页面发送来网站A的某个请求(可携带A的cookie),假装是A操作(比如,删除一条数据)
网站A:数据被删除了!!!
why
为什么呢?其实就是利用了请求的发送机制。
我们知道cookie是绑定到域名上的,如果网站B请求了网站A的接口,那么请求是会携带网站A的cookie到网站A的服务器。
网站A收到请求之后,根据携带的cookie,就是认为是这条请求是受害者发送过来的。
当然,我们都知道,受害者其实没有这个意思。
对cookie机制不了解的,可以看下楼主的文章 cookie & session
防范
讲到这,我们应该都知道CSRF会让别人假装我进行操作,那简直是太危险了,那么,我们来看以下要怎么防范CSRF的发生。
验证码
验证码,我们知道,CSRF就是在我们不知情的情况下发送来请求,那么如果请求需求交互,就可以防范CSRF了。
当然,如果所有请求都要做验证码的话,用户估计不想用我们的系统了,所以使用验证码的话还是要谨慎。
referer校验
看一下掘金的http请求,会发现请求头会带有referer字段,referer字段是自动携带的,表示请求来源。
那么,我们的接口可以做的处理就是对referer做一个校验,不允许的源不能进行操作,这样就可以阻止CSRF的发生啦。
不过referer校验也可以被绕过,如果用户发请求的时候,先用抓包工具改了referer参数,那么我们做的操作就没有用了。
token校验
token校验,应该说是CSRF防范的业界标准了。
token校验要配合cookie进行处理,登录的时候通过set-cookie,将一个sign保存在cookie中。
发送请求的时候,通过sign计算出token,然后再每条请求中携带token,服务器根据token进行校验,不通过就拒绝。
我们看一下掘金页面发送的请求,请求都携带了token参数。
注意:由于token校验是基于cookie的,所以如果网站被XSS的话,token防范也会失效的,这个时候要解决的就是XSS问题了。
time33
上面讲到sign可以计算出token,那么到底怎么算了,业界经典就是使用time33。time33是一个字符串哈希函数。
function time33(sign) {
let hash = 5381;
for (let i = 0, len = sign.length; i < len; ++i) {
hash += (hash << 5) + sign.charCodeAt(i);
}
return (hash & 0x7fffffff);
}
Q:为什么叫time33
A:因为一直在乘33
Q:为什么是5381
A:5381(001 010 100 000 101)据说hash后分布会更好
写在最后
CSRF的防范现在已经很完善了,接口做好配置,还是可以很好防范的~