正如我们在本章中看到的,授权/会话安全可能是个复杂的主题。下面是授权/会话管理技术最佳实践的一个大纲:
·使用SSL。任何包含敏感信息的流量都应该加密以避免嗅探攻击。
·按照RFC 2109,用Set-Cookie响应首部的Secure参数标记cookie。
·不要开发自己的授权。现成的授权功能,例如那些应用平台如ASP.NET和PHP自带的授权机制(我们将很快对此加以讨论),可能比最大的Web应用开发商从头开发的授权机制更多地得到了现实环境的考验。将安全事务交给专家,专注于你的核心业务。你因此遭受的攻击会更少;相信我们。
·不要在令牌中包含个人敏感数据。这么做不仅导致会话劫持(因为这种数据通常不是真正的秘密——有没有试过在Google上寻找某人的家庭地址?),而且如果这些数据泄露,用户失掉的会比随机生成的会话ID更多。攻击者可能盗取他们的官方ID、密码或者其他用于填写令牌的信息。
·在权限改变时重新生成会话ID。大部分Web应用在第一次请求URL时分配会话ID,甚至对匿名用户也这么做。如果用户登录,那么应用应该为用户创建和分派一个新的会话ID。这不仅代表该用户已经验证,而且减少了第一次访问没有通过SSL进行时的窃听攻击。这还能减缓本章前面讨论过的会话完成攻击,在这种攻击中,攻击者到达一个网站并且获得会话ID,然后用电子邮件发给受害者,让他们用攻击者已知的ID登录。
·实施会话时间限制以关闭重放攻击的窗口。在特定的不活跃期(比如10分钟)或者设定的时间(可能是30分钟)之后使状态信息和会话ID无效。除了相对与会话相关的期限之外,我们建议应用设置会话长度的绝对限制,以避免企图在将来修复会话ID的攻击。始终记住:服务器应该使ID或者令牌信息无效;不能依靠客户来完成这一工作。这能保护应用免遭会话重放攻击。
·实施并发登录限制。不允许用户拥有多个并发的已验证会话。这能够避免恶意的用户劫持或者猜测有效的会话ID。
·执行严格的输入校验。cookie名称和值和POST\GET和其他HTTP首部值一样,处于用户的完全控制之下,可以进行修改以包含应用程序不希望的数据。因此,必须在应用服务器上执行cookie值的严格输入校验,确保攻击者不能恶意修改cookie数据,利用安全漏洞。
成为还是模拟?
谈到Web应用授权,最重要的问题之一是:请求将在哪个安全(账户)上下文中运行?答案几乎总是定义了请求所能访问的资源(也就是授权)。下面是用于澄清这个常常被误解的概念的简单背景知识。正如第1章中我们讨论过的,Web应用是面向客户端-服务器的。对于服务器来说,实现客户端请求实际上有两种选项:
·使用服务器自己的身份执行请求(对Web应用来说是Web服务器/守护进程)。
·模拟客户(或者具有相似特权的其他身份)执行请求。在软件术语中,模拟意味着服务器进程生成一个线程,给予它客户的身份(也就是说,将客户的授权令牌连接到新的线程)。这个线程现在可以代替用户访问本地服务器资源,就像本章开始时介绍的简单授权模型。
注意 模拟的线程也可能访问远离第一个服务器的资源;Microsoft称其为委托(Delegation),要求特殊的配置和较高的权限级别。
Web应用使用刚才描述的两种选项,首先取决于Web守护进程的类型和版本,其次取决于请求的是文件系统对象还是启动服务器端执行程序(例如CGI或ISAPI应用)。例如,Microsoft IIS 6以前的版本始终模拟对文件系统对象的访问(不管是使用固定账户如IUSR_机器名,还是客户端指定的已验证账户)。对于可执行程序,默认不进行模拟,但是可以经过配置进行。IIS 6及更新版本上的ASP.NET应用的默认配置不进行模拟——所有请求在Network Service账户的上下文中执行;ASP.NET应用的模拟可以通过system.web/identity impersonate下的machine.config或web.config配置。
Apache不模拟对文件系统对象或者可执行程序的请求,而是在Web守护进程的安全上下文中进行所有工作(但是有一个附加模块可以通过setuid/setgid操作粗略地进行可执行程序的模拟)。
警告 因为Web应用授权几乎完全由Web服务器守护进程调度,所以要特别注意绕过标准授权机制的Web守护进程漏洞,如2001年发现的IIS Unicode和Double Decode问题。
在任何情况下,很明显运行Web服务器、servlet引擎、数据库或者其他应用组件的用户账户的权限应该尽可能少。我们在本章结尾处的“参考与延伸阅读”小节中包含了到多篇论文的链接,这些论文描述了IIS和Apache默认情况下使用的账户,以及配置它们的技术细节。
ASP.NET授权: 和许多Microsoft产品一样,IIS是可以组成复杂应用的一堆技术中的一个层次。对于决定采用Microsoft IIS web服务器产品的开发工作,采用他们的Web开发框架是非常实用的,这种框架是活动服务器页面(ASP),因为它集成到Microsoft更广泛的.NET编程系统中,所以现称ASP.NET。
ASP.NET提供一些非常令人信服的授权选项,细节太多无法在此一一说明。我们建议查看本章结尾处的“参考与延伸阅读”小节,理解ASP.NET提供的授权选项。
对于采用ASP.NET的人们,我们还要强调一点:如果你选择在web.config文件的<identity>元素中指定验证/授权凭据,你应该使用Aspnet_regiis.exe工具(对于ASP.NET版本2)或者Aspnet_setreg.exe工具(对于ASP.NET版本1.1)对其加密。关于如何使用这些工具的深入描述可以在本章结尾处的“参考与延伸阅读”中找到。