“山寨”SESSION讨论

luck0235 2008-12-22 11:56:29
“山寨”SESSION讨论

把用户状态用SESSION存在服务端还是用COOKIE存在客户端?一直有这个困惑但从未静下心来仔细思考。直到最近项目告一段落才得以清闲几日,整理了一下自己的想法,描述出来抛砖引玉,请各位指正和讨论。

案例描述:把场景精减,假设一个简单的会员系统,输入账号、密码登录后产生会员ID,并以会员ID作为登录凭证。

OK,上面的情形我想每个WEB开发者都遇到过,首先是使用Cookie存在的安全问题:

如果这是一个涉及支付的会员商城系统,用户篡改了客户端会员ID,那么就代表他能以任何其它人身份登录,我想这一定是致命的。很多开发者的做法是用可逆加密算法对COOKIE加密,比如3DES。但想想其实用户是能拿到加密前和加密后的数据的,这种情况我想再强大的加密算法也不会让人踏实。之前在网上还看到一些利用HTTP技巧对COOKIE进行处理的文章,但HTTP本身就是明文传输,这类解决方法我想也只能是治标不治本。

似乎安全是COOKIE不可逾越的一道障碍,如果换用SESSION呢:

我想99.99%的人还是不能破解SESSION的安全机制吧,SESSION在客户端存放了一个KEY,在服务端存放了真实数据,要获取真实数据就需要提供KEY,在物理上对数据进行了隔离。OK,SESSION是安全的。但假设我要对SESSION的规则做一些自定义的修改呢?比如常见的“记住密码”功能,让会员ID一直在服务端保留;比如去除超时限制,让SESSION像COOKIE一样可以不存在超时呢。很遗憾,微软对SESSION做了完美的封装,我能做的只有赋值和读取。写这篇文章的动机也就是因为遇到了如上的问题,再加上一直有着“山寨”情节,且山寨一个自定义的SESSION,请各位指正。

解决方案(如下图):


当会员登录后在客户端生成COOKIE值:会员ID和KEY。KEY将作为安全验证核心,同时在服务端Cache中添加KEY与会员ID的对应关系。当用户每次访问要求安全验证的页面时都必须提供KEY。如果在CACHE中存在KEY则允许访问,否则禁止访问。
之前准备将服务端的数据存放在数据库中,就像.NET提供的SESSION StateServer或SESSION SQLServer模式,但数据库与内存,两者在速度和性能上都差距颇大,权衡后决定用Cache+HashTable来实现。

然后我的项目有一个“记住密码”功能,所以KEY就要求在客户端用COOKIE长期保留,同时在服务端的数据库用一张表来记录这些“记住密码”的用户,表中包含了一个“过期时间”字段,单独的WIN服务程序定时清空过期的记录。最后让应用程序启动时把“记住密码”的这批用户KEY添加到CACHE中。

大概思路就是如此,套用了SESSION的原理,一些细节还未考虑周全,先将想法拿出来请各位指导一下,后面再开始编码实现。
...全文
461 48 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
48 条回复
切换为时间正序
请发表友善的回复…
发表回复
brood108 2008-12-24
  • 打赏
  • 举报
回复
所以这些系统是在登录环节尽量做足了安全验证,在交易的时候而不使用交易密码。
brood108 2008-12-24
  • 打赏
  • 举报
回复
回41楼的:
淘宝交易属于那种不频繁的交易,用交易密码显然没有问题。

我举个频繁交易的例子把:
比如联通的充值系统,后边有人拍着队在缴费,客服不停的在充值,总不能每次充值都输入一次交易密码把!
再举个例子,比如网吧游戏点卡销售系统,玩家排着队购买点卡,网管mm也总不能不厌其烦的一直重复输入那个交易密码把!

brood108 2008-12-24
  • 打赏
  • 举报
回复
[Quote=引用 sp1234 的回复:]
例子中假设一个服务器实时收集你的1万个客户的当时的操作的sign,或者知道你的其它任意信息,那么当我现在想模拟一个用户的信息时,我可以随便拿出一个来保持我对他的假冒身份,至少服务器是真假难辨。。。
[/Quote]

to:sp1234
我在27楼的回复已经说的很明白,验证成功后,需要记录本次成功的time的
你下次拿同一个包过去提交,一验证当前time跟最后一次成功登录的time一样,就通不过的,或者拿以前的旧包,一验证当前time比最后一次成功登录的time要早,也是通不过的。这有点类似于一次性密码的功效。
atx控件的作用仅仅提供了一个安全加密的作用,只是一般人根本没有这样用,是本人的独创,你也可以试着找一下这种方法是否有我还没有发觉的漏洞。

这样的设计在当时确实遇到一个问题,比如用户修改系统时间到2010年,登录成功后time就被记录成了最后登录2010年,如果用户在修改系统时间成正常时间在登录的话,当前时间总是早于上次成功登录时间就一直无法登录。
对于这个小问题,解决方法是:用服务器时间而不用本地时间,登录前用ajax获取服务器时间来做time。

niitnanfeng 2008-12-24
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 brood108 的回复:]
如果要是一个登录后需要频繁交易操作的系统,
那么交易密码显然是不合适的,每次输入太繁琐,而且频繁输入密码的安全性也不高。不如丛登录严格把关下而不用交易密码。
反之则可以考虑简单增加个交易密码就完事。
[/Quote]
要你那么说淘宝交易岂不是多此一举了?要想足够安全还是使用ssl证书登录。即使证书被别人给窃走了,导入证书还需要密码和身份认证。
anncesky 2008-12-24
  • 打赏
  • 举报
回复
[Quote=引用 46 楼 anncesky 的回复:]
引用 37 楼 sp1234 的回复:
或者Session到期过期之后,再访问此页面,你会看到SessionID是不变的。这是因为SessionID本来就是保存在cookie中的,并不会随着Session的丢失而丢失,SessionID唯一地标记会话的编码。


我前断时间仔细玩过session和cookie

sessionid是放在cookie中的,是放在临时cookie中,关于这个临时cookie我找了N久,没找到
哪位牛人找到可以跟我说说,谢谢了

用户只要第一次请求服务器,服务器…
[/Quote]

这个临时的cookie找不到,也就是说,LZ的方法安全性方面还比不上session
dingzhiming 2008-12-24
  • 打赏
  • 举报
回复
[Quote=引用 42 楼 brood108 的回复:]
这有点类似于一次性密码的功效。
[/Quote]
既然是一次性密码,那么下次又要重新登录的了。
但楼主的需求是“记住密码”,过期之前,下次可以继续使用。
anncesky 2008-12-24
  • 打赏
  • 举报
回复
[Quote=引用 37 楼 sp1234 的回复:]
或者Session到期过期之后,再访问此页面,你会看到SessionID是不变的。这是因为SessionID本来就是保存在cookie中的,并不会随着Session的丢失而丢失,SessionID唯一地标记会话的编码。
[/Quote]

我前断时间仔细玩过session和cookie

sessionid是放在cookie中的,是放在临时cookie中,关于这个临时cookie我找了N久,没找到
哪位牛人找到可以跟我说说,谢谢了

用户只要第一次请求服务器,服务器就会分配一个sessionid给客户端的临时cookie,接下来的用户请求
就把这个cookie一起传给服务器,在类似hashtable中根据sessionid查找对印用户信息

但是这个sessionid有时候并不是固定不变的
各位可以试试,当你的在服务器端没有把数据存入session对象时,用户每次请求发到服务器的sessionid是不一样的

还有,据ms的说法,同时在线超过一定数量时,多个用户sessionid可能相同,也就是说,共享一个会话数据
要大天下大乱了
dingzhiming 2008-12-24
  • 打赏
  • 举报
回复
关注!
vrhero 2008-12-23
  • 打赏
  • 举报
回复
实际上你要做的是分配给用户一个登录票据...该票据某种算法根据用户登录信息生成的唯一标识,其中不包含用户ID和密码等关键信息...服务器维护和分发此票据,用户登录后将此票据存入Cookies...至于服务器端你用Session还是Cache其实无关紧要...

当然这样做也无法保证客户端伪造登录票据,不过相对难度会大很多...除非使用证书和SSL传输,安全总是相对的...
suiqirui19872005 2008-12-23
  • 打赏
  • 举报
回复
有时对于分布式服务器,喜欢用memcached,将session存入一组服务器中,其他服务器再从中读取。

近阶段,微软与推出了类似于memcached,用于分布式的,可以存入数据对象
http://www.cnblogs.com/Terrylee/archive/2008/11/20/Microsoft-Distributed-Cache-Velocity-Part1.html
Robin 2008-12-23
  • 打赏
  • 举报
回复
这样好
  • 打赏
  • 举报
回复
我们也可以做一个ActiveX,反正ActiveX就是可以劫持用户机器的,它可以专门用来监听用户访问特定url时的特定信息例如账户、密码、所谓的电脑标识号,然后传递到我们的服务器上。如果我们希望访问某个网站,让这个ActiveX使用别人的信息自动提交这个信息就可以了。

ActiveX只是因为用的少,才被容易误认为是“加密”的手段。实际上,它也是劫持、窃取用户登录信息的关键手段。

为什么在普通的互联网应用上ActiveX没有使用起来,就是因为许多人其实就是用一个合理的借口来哄骗和劫持用户,例如过去国内下载网站猖獗时就借口给你免费下载软件而散步了不少广告插件来劫持用户的电脑强行弹出广告。
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 brood108 的回复:]
首先,你这样做,用不用key,安全级别是完全一样的。

不管是通过何种方式,我只要能搞到别人电脑上的cookie,
就是说得到id跟key对应的cookie值,那么我就可以丛任何地方来用该cookie来跳过登录直接访问你的系统了。

其次,要解决这个问题,我给你提供一下我们公司目前的解决方案把。
1,客户端存一个简单的cookie,存放加密后的id就够用了。
2,需要自动登录的用户,需要安装一个activex插件,安装成功后,取得用…
[/Quote]

这有可能是形同虚设。如果一个人能够监听到cookie,他同时就监听到你的activex插件向服务器传递的电脑标识号,收集起来留下来备用了。如果一个人可以伪造提交的cookie,它就同样地可以通过通讯手段传递一个合法的电脑标识号,而此时它的电脑根本不用安装你的这个ActiveX插件。
Fibona 2008-12-23
  • 打赏
  • 举报
回复
你还不如直接用cache记录用户信息呢,这样全在服务器内存中,只要cache还存在,肯定是安全的,不过占用服务器内存太大

关键点时,用Cookie的话,即使服务器重启了,即使Cache没有了,他还是可以根据用户名去自动登录

睡觉了,明天来看高手的回答

luck0235 2008-12-23
  • 打赏
  • 举报
回复
谢绝灌水,谢绝帮顶,无实质内容谢绝给分,谢谢合作。
  • 打赏
  • 举报
回复
[Quote=引用楼主 luck0235 的帖子:]
当会员登录后在客户端生成COOKIE值:会员ID和KEY[/Quote]

呵呵,有的时候,一张图足以让一个概念混乱,还不如一句话明白。

你的这句话终于让我明白你的意思。不过,实际上,你在cookie中只要保存数据库中为本次用户登录所分配的passport记录的编号就可以了。passport记录中可以保存所对应的用户,以及本地登录有效期时间(例如在2分钟之后),以及最后访问时间(当用户刷新最后访问时间的时候我们可以推迟其有效期时间)。

在服务器端的应用程序要取得一个编号的passport记录,会首先从Cache中取,如果没有则才会读取数据库并且同时放入Cache中,这样就可以尽量减少访问数据库的次数。而放入Cache时,设置了缓存依赖项,使得的当数据库的passport改变时此Cache自动过期。

因此,cookie中没有必要保存那么多登录信息,仅仅需要保存一个long型数字即可。
brood108 2008-12-23
  • 打赏
  • 举报
回复
如果要是一个登录后需要频繁交易操作的系统,
那么交易密码显然是不合适的,每次输入太繁琐,而且频繁输入密码的安全性也不高。不如丛登录严格把关下而不用交易密码。
反之则可以考虑简单增加个交易密码就完事。
hy_lihuan 2008-12-23
  • 打赏
  • 举报
回复
其实各种解决方案都有其优点和缺点,你需要做的尽量使用其优点,减少其缺点的暴露。
cookies的缺点是安全性、优点是在本地保存;既然你要能够减少用户登录的过程,本身就是降低了系统的安全性;
其次,在一些安全性较高的操作上保持数据的安全性就可以了,既目的性明确也减少对整个系统安全性的庞大分析。
比如:我登录网站是比较宽松的,要付钱的时候再次输入交易密码确保这个密码的安全性就好了。
brood108 2008-12-23
  • 打赏
  • 举报
回复
首先,你这样做,用不用key,安全级别是完全一样的。

不管是通过何种方式,我只要能搞到别人电脑上的cookie,
就是说得到id跟key对应的cookie值,那么我就可以丛任何地方来用该cookie来跳过登录直接访问你的系统了。

其次,要解决这个问题,我给你提供一下我们公司目前的解决方案把。
1,客户端存一个简单的cookie,存放加密后的id就够用了。
2,需要自动登录的用户,需要安装一个activex插件,安装成功后,取得用户的电脑标识号,存入数据库就可以了。
3,用户自动登录的时候,取得cookie里的id和用activex插件取得电脑标识号,跟数据库中的比较即可。
4,activex插件取得电脑标识号,可以这样获得:sin=md5(取得硬盘信息+网卡信息+key)key是自己约定好的一个字符串

但愿对你有帮助。
lovehongyun 2008-12-23
  • 打赏
  • 举报
回复
加载更多回复(28)

62,243

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧