心路
死生契阔,与子成说。执子之手,与子偕老。

  • 首页
  • 关于
  • MyIcy
  • 琐记(413)
  • 技术(221)
  • 八卦(105)
  • 读书(20)
  • RSS
  • 很感谢云舒兄弟去年推荐到阿里...
  • 信春哥,得永生....
  • 据说胡适有36个博士学位...
  • 我给你力吧...
  • 当前Blog无任何评论...
  • 最新论证:先有的嫖客后有的鸡...
  • 好的呀,非常感谢! 我这个当...
  • 云老大,将你的程序修改了下,...
  • cnbeta上有中文的...
  • 当前Blog无任何评论...
  • 舒舒,不要把我给你的邮件随便...
  • 本人有项目想和你合作,有意向...
  • hehe
  • 大哥,你好,Ttyutils的rpm或...
  • 很好
  •  
     
  • 黑小子's Blog
  • Nick's blog
  • sbilly的乌托邦
  • 80 sec
  • 段段的blog
  • 肉肉的洗手间
  • JY美女
  • 小叶子的空间
  • 螺螺的blog
  • 忽尔今秋
  • Icy's Blog
  • 虚拟面包
  • 涛涛的blog
  • Tomy's blog
  • 王俊的blog
  • 狐狸的叶子
  • demonalex's blog
  • Super*Hei's Blog
  •  
    Powered by: SaBlog
    从wap网站的认证授权到csrf的协议类比本质
    Submitted by 云舒 on 2009, February 22, 11:35 PM. 技术

    摘要:这个文章是周五开始酝酿的,前半部分是总结,最后一小段只是为了说明一下安全的相通性,将csrf类比到tcp协议,从协议的角度阐述一下csrf产生的本质原因。想不到写到一小半就腰酸背疼,大部分内容都只能草草带过,很多地方需要进一步解释,都没法深入的描述下去了。一直说要坚持健身,却从来没去过,是在是罪过,先凑合着看看吧,有问题还请指出一下。

    现在WAP站是越来越多了,尤其是SNS兴起之后。不过由于不同的手机不同的浏览器对cookie的支持不同,因此wap网站为了兼容性一般不能使用cookie做用户认证之后的身份鉴别。cookie是session的基础,因此session同样不可用。那么如何安全的实现wap网站不同用户的授权问题?这里简单总结一下可用的两种可靠的方案。根据这个总结,顺便引申一下普通网站的csrf问题。(虽然session的基础是cookie,但是这里还是把它们作为两种不同的东西来描述)

    第一种方案是伪session方案。先看看传统网站的session原理,客户端cookie中保存一个唯一的session id,这个id和服务器的一个文件对应,经过扩展之后这里可以是内存或者保存在数据库中内容。用户访问网站时,cookie里带上session id,服务器根据session id获取对应文件的内容,验证用户身份或执行其它操作。传统session的关键在于两点,第一点是服务器保存一个名字唯一的内容,可存储在文件,内存,数据库或者其它地方。第二点是客户端保存这个内容的那个唯一的名字,并在每次访问网站的时候带上。

    使用session方案时,在普通网站转变成wap网站之后主要存在二点改变,第一点是客户端要在没有cookie的情况下每次请求发起时将session id发送给服务器。简单地说,GET请求的时候可以直接将session id附加在URL之后,POST请求的时候session id作为form的隐含字段发送到服务端,服务器从内容中获取这个session id进而获取保存在服务器上session内容,进行权限验证方面的事项。最终get请求生成的url类似/getlist.do?sid=sessionid,post则为form中的隐含字段。

    其次的变化在于要在服务端实现和原始session略有不同的session生成读取设置机制,以及将session id传送给客户端的方法。服务端在用户登录成功之后根据算法生成一个session id,session id的生成可以使用足够长度的随机数,也可以使用不可逆的hash算法,例如MD5算法,session id = MD5(loginname + logintime + salt)。同时,使用session id做为文件名生成一个文件(当然也可以是内存,或者以session id为主键的数据库条目)保存用户的关键信息,例如用户登录名登录状态等。生成完毕,在返回登陆后的页面给客户端时,将session id附加在get请求的url和post请求的form之后。关于伪session的读取和设置,主要改变在于session id的位置,从来源于cookie变为来源于get参数或者post内容,这个非常简单,获取到session id之后直接修改对应的文件(或者内存,数据库条目)即可。

    通过上文的两点,即可在wap站点中实现一种session机制,作为登陆后的权限判断等操作的基础。随着新的web架构的发展,为了负载均衡的方便,更多的系统开始去中心化,客户端自己维持自己的状态,我在《Restful风格WEB架构需要注意的两点安全问题》也提到过。因此,有必要实现一种伪cookie机制来作为认证授权的基础。

    伪cookie机制和伪session机制的区别,与cookie机制和session机制的区别一样,都在于是否在客户端保存关键数据,session类机制客户端仅需要保存一个session id和服务端对应即可,服务端保存关键信息,而cookie类机制则全部保存在客户端。伪cookie机制和伪session机制的实现方法类似,服务端对客户端的设置以及客户端到服务端的发送完全一样,区别在于它们的生成。这是因为session id仅仅在客户端和服务端之间起对应作用,而cookie本身就需要作为验证的数据,所以使用cookie机制时要保证服务端能解密读取cookie本身的内容,这就决定伪cookie机制只能使用可逆的加密算法,而不能采用生成session id的MD5类HASH算法。

    今天比较累,就懒得细写为什么了,大致描述一下就算了。cookie的加密算法使用对称加密如AES,或者非对称的RSA等均可。生成时方法大致如下base64(RSA("uniqid=random()&loginname=test&loginresult=success&logintime=20090222235143", private_key)),签名可以md5(url+cookie+salt)实现。uniqid是用来在用户退出的时候使用的,logintime记录时间戳是用来自己实现伪cookie过期机制使用的,其它的好理解。至于为什么伪session机制不需要签名而此处需要签名,那是因为他们的安全要求不同。伪session的时候即使伪造了session id,但是由于session id对应的内容在服务端不存在,因此不存在安全问题。而伪cookie的授权机制,一旦加密算法破解出现了伪造的cookie,还可以通过加入salt的md5签名将其丢弃。

    继续快速推进。现在说说wap中的这种机制在普通网站中的作用——防御csrf攻击。这个很容易,简单的将伪cookie机制中的算法略作简化即可。使用签名自检验保证不伪造,使用时间戳保证不被重放,而且与传统的方案相比无需服务端对生成的随机token串做记忆对比。

    比较有意思的是csrf产生的原因,这里我不从web的角度去说,而尝试从协议的角度来解说一下。我主要的目的是想说,安全都是相通的。csrf简单的说就是用户登陆站点a之后,在访问站点b的时候,在站点b后台向站点a发起了一次请求,而且站点a执行了。从协议的角度来看,这是因为http协议在多次的get,response之间是无状态的,是混乱的。用户与a站点的交互之中,被插入了一个数据包,而且被a站点执行了。那么为什么tcp层不会发生这种包的插入执行最终导致混乱的结果?很简单,tcp包有seq和ack序列号。同样的,udp协议也有类似csrf的问题,协议中被插入伪造。但是基于udp的dns协议却是比较可靠的,为什么?还是因为dns请求和回应的时候有一个dns id存在。基于这种协议的类比,显然现在所有的csrf方案都是为http协议实现一个类似的协议id。

    作为协议的序列号来说,一般的都是由客户端生成的初始值,随后在客户端和服务端的交互中变化。而由于WEB客户端的原因,csrf防御方案实现的协议序列号只能由服务端主动生成,随后交互,变化。在tcp协议中,一个tcp session中知道seq和ack的初始值即可推断出其它包的序列号,某种意义上说与tcp类似,在csrf的防御中以用户的一次登录活动为协议id的一个生存周期,在安全上说是可以接受的。

    大雨之夜,睡觉。现在确实是老了一些,精力不济啊,才11点半就累得不行了。

     
    评论
    感觉本质就是不可预测性,其余的方法都是为了确保这个东东。
    闪人,睡觉。困困哇。
    Post by suddy on 2009, February 23, 12:02 AM
    顶。不错不错
    Post by G on 2009, February 23, 2:05 AM
    "在tcp协议中,一个tcp session中知道seq和ack的初始值即可推断出其它包的序列号,某种意义上说与tcp类似,在csrf的防御中以用户的一次登录活动为协议id的一个生存周期,在安全上说是可以接受的。"
    如果一次登录活动中序列号可以推断,那么其在csrf中提供的保护还是值得商榷的。
    Post by GaRY on 2009, February 23, 2:36 AM
    我的意思是说,每次登录生成一个序列号,而这个序列号的生存周期一直保持到这次登陆注销或者这次登陆的cookie被强制失效的时候。这个长度我觉得是可以接受的,不用每个请求都是独一无二的。
    Post by 云舒 on 2009, February 23, 9:27 AM
    是这样的,现有的解决办法也是通过token来实现了一个两步的序列,因为HTTP里实现两步的序列就足够了。
    Post by System on 2009, February 23, 2:42 PM
    这个 序列号 不唯一?我 用 OPERA 登录 WAP 百度 然后 记住SSID 然后 退出 然后在登录 再推出 然后用第一次的 SSID 登录 显示 没登录 但是 手机却能利用以前登录的 不知道明白不
    Post by t_h4ck on 2009, April 2, 1:03 PM
    那如果cookie被劫持了呢,完成可以通过sniffer来获取cookie信息,然后模拟一份完全一样的cookie信息,这种方法用加密与签名是否能解决这个问题呢
    Post by tomijerry on 2009, December 12, 12:16 AM
    添加评论
    您的名字:
    您的E-mail:
    评论内容:
    验证码:
    Processed in 0.353121 second(s)