WEB系统安全架构需注意的问题

顺便先提一下所谓当前流行的WEB架构。在网络架构方面,目前流行的趋势和以前传统的门户网站采用七层交换,或者四层交换集中式部署做负载均衡不同,比较倾向于在物理位置上做分布式节点,通过智能DNS引导用户就近访问。这些CDN节点,有的是实际的WEB服务器,但是大多数可能只是一些Squid或者 Nginx之类的反向代理。这样做的好处第一是有更好的用户体验,第二是在拒绝服务攻击时,也有更灵活的应对方式。

鉴于系统分布式部署的趋势,因此在编码方面,也就开始流行刺提到过的Restful风格。所谓Restful风格,本质来说,就是客户端自己维持自己的状态,而且服务端信任这个客户端维持的状态。根据从客户端获取到的不同的状态,返回不同的页面。这里尽量的减少了服务端的判断等工作,让客户端对WEB系统的依赖性减轻,服务端做的仅仅是根据状态返回结果,并且在需要时为服务器设置一个新的状态,即所谓状态变迁。这点和P2P的去中心化有些类似,客户端不太在意自己连接到了哪一个服务器上面,只要自己维持着自己的状态,连接到WEB系统的任意一个服务器得到的结果都是一样的。目前流行的做法,就是不适用 session仅仅使用cookie,当然使用数据库session也是可以的。但是我觉得尽量把这些事情给客户端去做更好,减少数据库服务器的维护成本和故障风险,去中心化彻底一些。

目前这种分布式缓存节点大量使用,以及客户端自己维持状态的架构的流行,带来的两个安全风险就是敏感内容缓存的风险,以及客户端状态窃取或伪造的风险,而且前所未有的突出。

关于客户端维护的状态检验以及反窃取,关键点在于对cookie的加密算法强度以及完整性检验可靠度。在客户端状态被窃取时降低风险,我提到过cookie加入时间戳的方案,这个在刺的文章里有很详细的探讨,包后后面很多评论。

 

关于用户退出以及反窃取这里,再提一点。使用Session的方案,用户退出时在服务端销毁Session即可。即使有人盗取了cookie,使用 cookie里面保存的sessionid做刷新也是无效的,因为session实体已经在服务器上不存在了。新的无session方案中,这方面实现起来会麻烦一些。我的看法是,需要一个数据库记录用户的注销状态。当用户退出时,清空用户的cookie,同时在数据库中写入该用户已经登陆,下次不再使用 cookie认证,强制要求输入密码登陆。这样解决了cookie被盗取但是没超时的情况下,用户退出被盗取的cookie也不失效的问题。可惜的是这样又加上了一个数据库,那么结合起来看,把Session存入一个集中的数据库,在部署上并不比单纯的使用cookie差多少。

敏感内容缓存风险,主要是指用户A访问CDN上某个节点的时候,查看了一些包含自身信息在内的页面,而WEB系统在缓存方面没有做到足够的安全性,可能会导致这些敏感信息被用户B无意中看到。虽然缓存服务器可能不会缓存这些内容,但是随着缓存接点的急剧扩张,小几率的问题也会逐渐放大。就这个问题而言,可以在缓存服务器和代码两个点中的任意一个采取措施。虽然可以通过配置代理服务器策略保证安全,但是一般来说,防御应该是多层的,立体的,必须在代码中对缓存作出明确的控制。因为对于安全来说,需要尽可能的在不安全的环境中的保证系统的安全。代码中不做安全控制,这次部署的缓存系统是安全的,下次部署的缓存系统则可能出现疏忽。更何况,其他第三方无法控制的缓存服务器。

WEB系统中对缓存的控制,在RFC2616中14.9节有详细的描述。主要有public,private,no-cache,no-store等选项,具体描述可以仔细阅读RFC文档。值得一说的是no-cache和no-store的区别,no-store是比no-cache更严格的控制,按照 RFC原文:Even when this directive is associated with a response, users might explicitly store such a response outside of the caching system (e.g., with a "Save As" dialog).

总的来说,这种流行的架构看重分布式部署,和客户端状态维持,因此在架构中,更需要考虑缓存的安全以及客户端cookie的安全。在编码之初,就要关注到这些问题,到后期再改,就会来不及了

 

本文出自:http://laoxiege.blog.sohu.com/110867388.html

你可能感兴趣的:(Web)