| 本章内容 | |
| 目标 | |
| 适用范围 | |
| 如何使用本章内容 | |
| 互连环境 | |
| 基础知识 | |
| 综合利用各种技术 | |
| 设计原则 | |
| 摘要 |
构建安全的分布式 Web 应用程序是一项极具挑战性的任务。应用程序的安全程度受应用程序中的最薄弱环节制约,而分布式应用程序包含许多组件。要使这些组件安全地协作,您需要掌握多种产品和技术的基础知识。
本章阐述了构建安全的分布式 Web 应用程序的基础:身份验证、授权和安全通信。此外,其中还介绍了构建分布式 Web 应用程序时应遵循的一组重要安全原则。
本章的目标是:
| • | 帮助您了解身份验证、授权和安全通信这些术语在本指南中的含义。 |
| • | 从更高级别帮助您了解 ASP.NET Web 应用程序的总体结构。这意味着了解组成该体系结构的技术以及每种技术提供的身份验证、授权和安全通信选项。 |
| • | 帮助您了解作为本指南其余内容的基础的重要安全原则。 |
本章适用于以下产品和技术:
| • | Windows XP 或 Windows 2000 Server 和更高版本的操作系统 |
| • | .NET Framework 1.0 版以及更高版本 |
| • | ASP.NET 1.0 |
若要学好本章内容:
| • | 您必须熟悉 Microsoft 产品和技术的用途,包括 Windows、SQL Server 2000、Internet 信息服务、.NET Framework 以及企业服务 (COM+)。 |
| • | 您必须有开发 ASP.NET Web 应用程序的经验。 |
如果您已经知道如何构建安全的应用程序,那么您在构建 .NET Web 应用程序时能够应用所掌握的知识吗?在目前基于 Web 的分布式应用程序环境中,Web 服务将公司与公司连到一起,将公司与客户连到一起;在这种互连模式下,应用程序会有不同程度的公开,比如公开给 Intranet、Extranet 和 Internet 上的用户。您能在这种应用环境中应用所掌握的知识吗?
请考虑一下这种互连环境的几点基本特征:
| • | Web 服务使用 SOAP、可扩展标记语言 (XML) 和超文本传输协议 (HTTP) 等标准,但它们基本使用纯文本来传递潜在的机密信息。 |
| • | Internet B2C 应用程序通过 Web 传递机密数据。 |
| • | Extranet B2B 应用程序模糊了信任界线,允许合作伙伴公司中的其他应用程序调用应用程序。 |
| • | 在维护工资表和人力资源 (HR) 应用程序的机密性方面,Intranet 应用程序也存在风险。此类应用程序尤其容易因管理员不负责任和某些员工心怀不满而遭受攻击。 |
任何成功的应用程序安全策略都具有牢固的基础,即综合利用身份验证、授权和安全通信机制来保护机密数据的安全和完整性。在继续介绍前,很有必要对这些重要概念进行定义。在第 3 章身份验证和授权中,我们将介绍如何组合各种身份验证和授权机制来提供可靠的安全方案。
身份验证可明确识别应用程序的客户端,客户端可能包括最终用户、服务、进程或计算机。在安全术语中,经过身份验证的客户端称为主体。
身份验证在分布式 Web 应用程序的所有层中进行。最终用户通常需要输入用户名和密码来由 Web 应用程序对其进行初始验证。接着,当中间层应用程序服务器(如果体系结构中包含此类服务器)和数据库服务器处理最终用户的请求时,它们将对用户执行身份验证以确认和处理该请求。
在许多应用程序中,下游服务器和组件不会对最终用户进行身份验证,而是对上游应用程序这个实体进行身份验证以了解信任关系,在确认可以信任上游应用程序已正确验证该用户并授权后,将转发该请求。
适用于 ASP.NET 应用程序开发的多种身份验证机制将在第 2 章 ASP.NET 应用程序的安全模型中进行深入讨论。
授权过程用于控制经过身份验证的客户端可以访问哪些资源和操作。资源包括文件、数据库、表、行等等,以及注册表项和配置数据等系统级资源。
许多 Web 应用程序都授权客户端访问通过方法公开的操作,而不是直接访问底层资源,这主要是考虑到可伸缩性和易于管理性。这意味着,使用诸如 Windows ACL 等平台级安全机制来保护系统级资源仍是必要的。许多常见的应用程序级授权方案都使用角色来将用户分组,同一个组中的用户在应用程序中共享相同的权限。
ASP.NET 应用程序开发人员可以使用的各种授权方式和网关守卫将在第 2 章 ASP.NET 应用程序的安全模型中进行深入讨论。
许多应用程序都在应用层之间传递机密数据,例如从数据库服务器到浏览器或反之。机密数据包括银行帐户详细信息、信用卡号码、工资单数据等等。此外,在网络上传递登录凭据时,应用程序还必须保护这些凭据的安全。
安全通信提供以下两项功能:
| • | 保密性。保密性是指确保数据处于私有和保密状态,并且不会被可能使用网络监控软件的窃听者查看到。通常借助加密来达到保密目的。 |
| • | 完整性。安全的通信通道还必须能确保数据受到保护,以防止数据在传输过程中遭到意外或蓄意(恶意)的修改。完整性通常是通过使用“消息身份验证代码”(Message Authentication Code, MAC) 实现的。 |
由于公司网络内部会出现许多意想不到的信息泄露和安全漏洞,因此,在防火墙内外应用安全通信技术非常重要。
有关安全通信和可用的各种方案的信息,将在第 4 章安全通信中深入讨论。
ASP.NET Web 应用程序是使用许多不同的技术和产品开发的。为建立纵深防御型安全策略,需要在应用程序的多个层上应用各种身份验证、授权和安全通信方案。
图 1 总结了各种技术及其提供的主要身份验证和授权方式。

图 1
.NET Web 应用程序安全
以后各章中介绍的操作指导,都遵守多种至关重要的原则。您应当了解这些原则并在应用程序设计过程中进行应用:
| • | 采用最少权限的原则。运行脚本或执行代码的进程应当尽可能用权限最少的帐户运行,从而在进程安全受到危害时限制可能造成的损坏。如果恶意用户设法将代码注入某个服务器进程,那么授予该进程的权限会在很大程度上决定该用户可执行的操作类型。应当将需要更高信任级别(和更高权限)的代码分配在单独的进程内以进行隔离。 |
| • | 使用纵深防御。在应用程序中的每一层和每个子系统中设置检查点。检查点是网关守卫,它们确保只有经过身份验证和授权的用户才能访问下一个下游层。 |
| • | 不要信任用户输入。应用程序应该彻底验证所有用户输入,然后再根据用户输入执行操作。验证可能包括筛选特殊字符。针对用户意外地操作失误和某些人通过在系统中注入恶意命令蓄意进行攻击的情况,这种预防性措施对应用程序起到了保护作用。常见的例子包括 SQL 注入攻击、脚本注入和缓冲区溢出。 |
| • | 使用默认安全设置。开发人员往往仅仅为了使应用程序运行而使用安全性较低的设置。如果应用程序所需的功能使您不得不减小默认安全设置的安全级别或更改这些默认的安全设置,请在更改前测试更改所带来的后果并了解可能的隐患。 |
| • | 不要通过隐藏来保障安全。尝试使用让人迷惑的变量名来隐藏机密信息或将它们存储在不常用的文件位置,这些方法都不能提供安全保障。以上操作类似于“捉迷藏”,而最好的方法是使用平台功能或使用已被证实可行的技术来保护数据。 |
| • | 在关口进行检查。您不必总是将用户的安全上下文传递到后端来进行授权检查。这种做法在分布式系统中通常并不是最佳选择。在关口检查客户端指的是在第一个身份验证点(例如,Web 服务器上的 Web 应用程序内)授予用户权限,并确定允许用户访问的资源和操作(可能由下游服务提供)。 |
| • | 假定外部系统是不安全的系统。如果外部系统不归您所有,不要假定有人为您保证安全。 |
| • | 减小表面区域。避免公开不需要公开的信息。如果公开这些信息,就有可能导致更多安全漏洞。同时,处理错误的方式一定要适当。向最终用户返回错误消息时,不要公开任何不需要公开的信息。 |
| • | 以安全的方式显示错误消息。如果应用程序失败,一定要保护好机密数据。同时,不要在错误消息中提供过于详细的数据,也就是不要提供任何有助于攻击者发现应用程序漏洞的详细信息。详细的错误信息应写入 Windows 事件日志。 |
| • | 不要忘记您的安全程度受最薄弱环节制约。考虑安全性时,应该将应用程序所有层的安全性都考虑在内。 |
| • | 禁止不使用的内容。您可以通过禁用应用程序不需要的模块和组件来去除一些潜在的漏洞。例如,如果应用程序不使用输出缓存,则应禁用 ASP.NET 输出缓存模块。这样,即使以后在该模块中发现安全漏洞,应用程序也不会受到威胁。 |
本章提供了一些基本信息;通过了解这些信息,您可以为阅读本指南的其余部分做好准备。后面各章中将广泛使用和参考本章介绍的重要术语和原则,因此您一定要熟悉这些术语和原则。