转载:http://news.ctocio.com.cn/474/12462474_2.shtml
最近服务器也经常出现session串号的问题,于是在网上找,找到了这个,分析的在理,也顺利解决了我遇到的困难。
附:技术专家对中国研究生招生信息网和新浪微博网站分析过程
1、网站基本情况:
yz.chsi.com.cn域名的唯一解析IP为 211.151.242.181;该网站其他资源文件如图片,CSS,JS等,统一走的是 t1.chsi.com.cn至t4.chsi.com.cn 4个子域名,未使用CDN服务;该网站动态程序语言是JSP,WEB服务器是Nginx。
2、帐号管理方式:
用户在未登录状态下访问首页,也会分配一个SESSIONID(这点和一般网站不同)。登录后会分配一个新的SESSIONID,刷新页面时SESSIONID不会变化。此SESSIONID是用户的唯一标识,用户相关信息在服务端存。
而当用户登录后,在请求页面时会将此SESSIONID作为参数发放给服务端,服务端根据此ID取得用户信息后,输出到页面中,页面程序无法判别信息的真实性。
图3:对中国研究生招生信息网的简单分析
3、技术分析过程:
a)从用户反馈的现象分析,原先是一个帐号,刷新页面就变成了另一个帐号,而在这个网站上,SESSIONID是用户身份的唯一标识,所以如果SESSIONID发生改变了,从服务端返回的帐号信息就变了(前提是另一个SESSIONID对应的用户存在,而且处于登录状态)。
b)但是SESSIONID怎么会发生变化呢?有两种可能:一种是本地的SESSIONID被篡改,一种是服务端返回的SESSIONID发生了变化。
①本地被篡改的概率相对比较小,木马虽然存在,大多是偷盗,篡改对木马带不来直接的利益,而且很容易发现。
②但是按照SESSION的设定,在一次客户端和服务端的连接中,SESSIONID是不会变化的。所以服务端返回的JSESSIONID发生变化基本上也不可能。
c)只有当用户从未登录变成登录时,SESSIONID才会发生变化,但为什么会变成另一个帐号,而不是登录的这个帐号,最大的可能性是服务端将同一个SESSIONID返回给两个不同的用户,那这两个用户就会看到同一个帐号,其中一个用户就串号了。
①发生以上情况,不排除服务端生成SESSIONID有bug,随机值取得不对,但这种情况发生的概率极小。目前生成SESSIONID的函数都是封装的,java和php都有。
②如果服务端不会出错,唯一的可能性就是客户端和服务端中有第三者,第三者把SESSIONID弄重了。这第三者就是ISP缓存服务器。
4、 验证结果:
a) 我们在本地构建了一个ISP缓存的模拟环境,成功重现了一个用户帐号变成另一个用户帐号的串号现象,并且能做到像用户反馈的“可以直接登录修改报名信息”。
b) 但同时串2个帐号的情况,需要在一种特别组合的情况下才出现,这个概率很小。我们仍在积极联系反馈的用户,验证我们对此事情的分析。
ISP缓存的技术说明:
1、ISP缓存,本身是一种宽带接入提供商给网页批量访问加速的技术。ISP会将当前访问量较大的网页内容放到ISP服务器的缓存中,当有新的用户请求相同内容时,可以直接从缓存中发送相关信息,不必每次都去访问真正的网站,从而加快了不同用户对相同内容的访问速度,同时也能节省网间流量结算成本。
2、ISP缓存主要以缓存静态页面为主,比如新浪的新闻页。
3、 如果ISP的缓存中的网页带有用户SESSIONID信息,就可能发生登录串号现象。当用户A登录时服务端返回页面内容被ISP缓存,这时同网络的用户B 访问该网站,直接取得了刚才ISP缓存的信息,而该缓存信息中包含有用户A的SESSIONID(此时用户A还未退出),这样用户B处就显示出了A的信息。
新浪微博网站分析结果如下:
1、 新浪微博的登录验证与weibo.com 及 sina.com.cn 两个域名均有关联
2、 单独删除任意一个域名下的COOKIE及SESSION均不影响当前登录状态
3、 新浪微博的登录验证机制比较复杂,为多冗余多关键字关联生效
4、 在未能准确删除全部关键KEY前提下,删除部分会在重新刷新后自动生成
5、 目前新浪微博采用了https方式来登录,可以避免被ISP缓存。
6、 使用目前的新浪微博登录系统,在ISP缓存模拟环境中测试,并未重现微博串号现象。
图4:对新浪微博页面的简单分析
ISP缓存导致登录串号现象概率不高的原因:
1、 对网页的缓存一般是小的宽带接入提供商才采用,这种方式能提升访问速度,节省成本,但也会有后遗症,大的宽带接入提供商一般不敢随便采用。
2、 同一个宽带接入提供商下的两个用户,在缓存失效时间内同时登录某一个网站时,才会出现串号,这种概率相对比较低一些。
ISP缓存导致登录串号的解决方案:
1、 最好的解决方法是使用https来登录,因为是通过非对称加密,缓存设备无法得到服务器端的私钥,所以可以避免被ISP缓存。
2、 如果觉得实施成本高,或需要快速解决,可以在请求设置SESSIONID的网页链接中增加一个随机数参数,来临时绕过ISP缓存,但这样可能会增加网站自身服务器的压力,同时宽带接入提供商也可以调整缓存策略,忽略这些随机参数。
3、 网站也可以在SESSIONID的生成规则中加入生成IP的校验规则,这样至少可以确保即使SESSIONID串号了,网站自己也能发现并马上退出登录,从而不影响用户隐私。
**************************************************************************************
另外也有不同的意见:(这个也是我一直在思考的,是否有这种可能,查看了Tomcat生成sessionID的源码,不敢肯定啊,惭愧。。。)
session的id一般的是保存在cookie里面的,访问时客户端的id同服务器端的id相匹配。
说到微博串号的原因。我觉得有两种可能(纯属猜测):
- 一种有可能是因为算法问题导致的id在生成的时候出现了“碰撞",这种情况一般很难遇到,但是基于微博巨大的用户数量因而这类碰撞的产生就会有可能发生,毕竟基数太大了,难免有特例。
- 另一种,目前的服务器后台一般的都是集群处理的,有可能是在处理并行的时候没有处理好,有可能两台不同的服务器为不同的账号生成了相同的id
运营商缓存了session id,有点常识确实不会这么做,不过不排除运营商缓存的bug。
我们的动态页面就被缓存过,所以他缓存个session id,也没什么奇怪的。
一般干这种事的,都是长城宽带,电信通这些小运营商。