前端安全 - CSRF

321 阅读3分钟

上一篇文章讲完了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的防范现在已经很完善了,接口做好配置,还是可以很好防范的~