csrf跨站伪造请求

117 阅读3分钟

building_town_historic_europe-99049.jpg

前言

我们在浏览网站的时候,有时需要进行登录操作才可以有权去做些事情(比如点赞,收藏,评论之类的),那么就需要某些东西来记录我们登录的状态,像cookie,session,token,jwt(Json Web Token) 这些。

举个栗子:

以session为例

当我们登录时,网页会将用户信息(账号密码)发送给服务器,服务器验证是本人以后,就会在session中存放用户的登录信息,然后再把生成的sessionID发送给 (通过响应头的Set-Cookie设置) 客户端

并在客户端cookie中存放,下次用户再进行一些请求时(比如评论),就会携带这个cookie过去,这样网站就可以确定是你要评论

csrf跨站请求伪造

csrf跨站请求伪造是个啥? 以上面的图为例,看看它到底是个啥

当你在正常网站浏览时,忘记退出登录就去访问了一些非法网站,这时候非法网站就可以利用你的登录信息去模拟你的行为,评论不良信息看起来好像不是很严重,但是如果是转账呢?就算是关闭浏览器再去访问网站B也不能保证cookie就被销毁了,因为可以设置过期时间的。

举个例子

这里有一个运行在端口为3000的网站,还有一个运行在端口为4000的非法网站,3000的是模拟发表正常评论,4000则是点击领取优惠券,实际是在发表非法评论

webA提交评论

webB发布非法评论

点击提交评论后:

会带着cookie给服务器

post参数为:

点击领取优惠券后:

携带cookie给服务器

post参数为:

虽然举的例子不好,不过也可以看出来,登录以后去访问非法网站B并点击领取优惠券以后,服务器还是响应给了这个网站,可见这是多危险的一件事

如何防护csrf跨站请求伪造

  • 验证Referer⽅式:

    • 优点:使⽤⽅便,开发简单,⼀定程度上能预防CSRF攻击
    • 缺点:这种机制完全依托于浏览器,Referer字段容易被故意篡改,或者被禁⽤。

    从上面不同网站发起请求的请求头中可以看到referer是不一样的,它代表的是该网站的域名,那么服务器可以通过这个去验证是否是来自自己的网站,但是referer很容易被改写,而且有些用户也会禁用referer字段,所以这个也不是很安全

  • 自定义HTTP请求头 想要自定义HTTP请求头就要用到AJAX,而AJAX又有跨域的问题,所以非法网站就没法通过这种方式来攻击正常网站了

比如我在登录时就给客户端发送一个cookie,里面存的是一些随机数,在点击评论时自定义请求头,值为我刚刚的cookie的值,再与服务器校验。

下面划红线的就是我设置的请求头信息

由于webB没有设置请求头所以响应回来的结果是失败

当然防护不止这两种方法,大家可以去扩展一下其他的方法。