出现现象:
公司的项目使用SWFUpload上传文件,最近突然发现上传302。
我用谷歌浏览器调试查看上传的post请求,原来是被重定向到了首页(这就说明session掉了)。
为什么上传会导致session掉?
1、经检查,原因是上传文件的post请求中没有携带cookie。如图:
2、所以服务器默认该用户未登录,重新(set-cookie)响应回了一个新的cookie给用户,如图:
3、此时浏览器拿到新的cookie,用新的cookie去请求,服务器判断此用户未登录,就重定向到了首页。
原来的session也就丢失了。
为什么没有携带Cookie?
这就要从SWFUpload上传原理说起了,SWFUpload是用Flash上传文件。在上传的时候使用的是和浏览器不同的会话,flash的SWFUpload上传利用socket套接字进行通信,所以导致session和原来上一次的会话不同,导致session丢失。
同时浏览器控制台打印了如下信息:(实例图片)貌似是需要设置SameSite属性。
SameSite
属性的作用是什么?
拿谷歌浏览器50来说, Cookie 新增加了一个SameSite
属性,用来防止 CSRF 攻击和用户追踪。
SameSite有三个值:
1、Strict。(Strict
最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。)
2、Lax。(Lax
规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。)
3、None。(网站可以选择显式关闭SameSite
属性,将其设为None
。不过,前提是必须同时设置Secure
属性(Cookie 只能通过 HTTPS 协议发送),否则无效。)
什么是跨站请求伪造CSRF?
它是一个域网站向另一个域网站发起请求的简单功能。攻击者通过一些技术手段欺骗用户使用浏览器去访问一个自己曾经认证过的网站并执行一些敏感操作(如转账)。
举例解释:骗子诱导我点开了某个钓鱼网站,而钓鱼网站会调用银行的转账接口。正常情况下我没有登陆,自然转账失败。
但是如果我刚刚登陆了网银,还没退出来呢?这时钓鱼网站调用银行接口时,浏览器就会自动携带cookie去请求,而此时银行session还没过期,服务器就会认定为合法用户,转账就成功了。这就是跨站请求伪造。
最终解决办法:
用户首次访问系统时,服务器返回的cookie多增加一个SameSite=None属性