Web 应用程序的基本安全实施策略

更新:2007 年 11 月

创建安全的 Web 应用程序这一主题涉及的内容非常广泛。它要求进行学习以了解安全漏洞。您还需要熟悉 Windows 的安全功能、.NET Framework 和 ASP.NET。最后,必须了解如何使用这些安全功能来防御威胁。

即使您在安全性方面的经验不够丰富,也应该采取一些基本措施来保护您的 Web 应用程序。下面的列表提供了适用于所有 Web 应用程序而且您应当遵循的最低安全性准则:

  • 常规 Web 应用程序安全性建议

  • 使用最少特权运行应用程序

  • 了解您的用户

  • 防止恶意用户的输入

  • 安全地访问数据库

  • 创建安全的错误消息

  • 安全地保守秘密

  • 安全地使用 Cookie

  • 防止拒绝服务威胁

    zdh19h94.alert_note(zh-cn,VS.90).gif说明:

    有关可帮助您设计、开发、配置和部署更安全的 ASP.NET Web 应用程序的全面、详细的安全指南,请参见“Microsoft Patterns and Practices”(Microsoft 模式和实践)网站中的安全模块。

常规 Web 应用程序安全性建议

如果恶意用户可以使用简单方法进入您的计算机,即使是最精心设计的应用程序安全措施也会失败。请遵循这些指导:

  • 经常进行备份,并将备份存放在安全的场所。

  • 将您的 Web 服务器计算机放置在安全的场所,这样,未经授权的用户就无法使用它、关闭它或带走它。

  • 使用 Windows NTFS 文件系统,不使用 FAT32。同 FAT32 相比,NTFS 的安全性有很大程度的提高。有关详细信息,请参见 Windows 文档。

  • 使用不易破解的密码,确保 Web 服务器计算机和同一网络上的所有计算机的安全。

  • 确保 IIS 的安全。有关详细信息,请参见“Microsoft TechNet Security Center”(Microsoft TechNet 安全中心)网站。

  • 关闭不使用的端口并关闭不使用的服务。

  • 运行监视入站和出站通信的病毒检查程序。

  • 建立并实施以下策略:禁止用户将其密码记在容易找到的位置。

  • 使用防火墙。有关建议,请参见 Microsoft 安全站点上的“Microsoft Firewall Guidelines”(Microsoft 防火墙准则)

  • 安装 Microsoft 和其他供应商提供的最新安全修补程序。例如,“Microsoft TechNet Security Center”(Microsoft TechNet 安全中心)网站中提供了所有 Microsoft 产品的最新安全公告的列表。其他供应商也有类似站点。

  • 使用 Windows 事件日志记录,并且经常检查这些日志,以查找可疑活动。这样的活动包括:反复尝试登录您的系统,以及向您的 Web 服务器发出数量巨大的请求。

使用最少特权运行应用程序

当您的应用程序运行时,它运行在一个具有本地计算机(还可能是远程计算机)的特定特权的上下文中。有关配置应用程序标识的信息,请参见配置 ASP.NET 进程标识。若要使用最少特权运行,请遵循以下准则:

  • 不要以系统用户(管理员)身份运行应用程序。

  • 在具有最少实用特权的上下文中运行应用程序。

  • 设置对应用程序所需的所有资源的权限(ACL 或访问控制列表)。使用最少的容许设置。例如,如果在您的应用程序中是可行的,则将文件设置为只读。有关 ASP.NET 应用程序标识所需的最少 ACL 权限的列表,请参见 ASP.NET 必需的访问控制列表 (ACL)

  • 将您的 Web 应用程序的文件保存在应用程序根目录下的一个文件夹中。不要让用户指定在应用程序中进行文件访问的路径。这样有助于防止用户访问服务器的根目录。

了解您的用户

在许多应用程序中,用户可以匿名访问站点(无需提供凭据)。如果是这样,则您的应用程序通过在预定义用户的上下文中运行即可访问资源。默认情况下,此上下文是 Web 服务器计算机上的本地 ASPNET 用户(在 Windows 2000 或 Windows XP 上)或 NETWORK SERVICE 用户(在 Windows Server 2003 上)。若要仅允许已授权用户进行访问,请遵循以下准则:

  • 如果您的应用程序是 Intranet 应用程序,则将其配置为使用 Windows 集成安全性。这样,用户的登录凭据就可以用于访问资源。有关更多信息,请参见 ASP.NET 模拟

  • 如果您需要从用户收集凭据,则使用其中的一种 ASP.NET 身份验证策略。有关示例,请参见使用成员资格管理用户

防止恶意用户的输入

通常,决不假定从用户获得的输入是安全的。对恶意用户来说,从客户端向您的应用程序发送潜在危险的信息是很容易的。若要防止恶意输入,请遵循以下准则:

  • 在 ASP.NET 网页中,筛选用户输入以查找 HTML 标记,其中可能包含脚本。有关详细信息,请参见如何:通过对字符串应用 HTML 编码在 Web 应用程序中防止脚本侵入

  • 决不回显(显示)未经筛选的用户输入。在显示不受信任的信息之前,对 HTML 进行编码以将潜在有害的脚本转换为显示字符串。

  • 切不可将未经筛选的用户输入存储在数据库中。

  • 如果要接受来自用户的一些 HTML,则手动筛选它。在您的筛选器中,显式定义将要接受的内容。不要创建一个试图筛选出恶意输入的筛选器;因为预料到所有可能的恶意输入是非常困难的。

  • 不要假设您从 HTTP 请求标头(在 HttpRequest 对象中)获得的信息是安全的。对查询字符串、Cookie 等采取安全措施。注意浏览器向服务器报告的信息(用户代理信息)可以假冒,假如它在您的应用程序中是重要的。

  • 如有可能,不要将敏感信息(如隐藏域或 Cookie)存储在可从浏览器访问的位置。例如,不要将密码存储在 Cookie 中。

    zdh19h94.alert_note(zh-cn,VS.90).gif说明:

    视图状态以编码格式存储在隐藏字段中。默认情况下,它包含消息身份验证代码 (MAC),以便页可以确定视图状态是否已被篡改。如果要在视图状态中存储敏感信息,请通过将页的 ViewStateEncryptionMode 属性设置为 true 来加密信息。

安全地访问数据库

数据库通常具有它们自己的安全性。安全 Web 应用程序的一个重要方面是设计一种应用程序安全地访问数据库的方法。请遵循这些指导:

  • 使用数据库的内在安全性来限制可以访问数据库资源的人员。确切的策略取决于您的数据库和应用程序:

    • 如果在您的应用程序中切实可行,请使用集成安全性以便只有 Windows 授权的用户才能访问数据库。与将显式凭据传递到数据库相比,集成安全性更安全。

    • 如果您的应用程序使用匿名访问,请创建具有非常有限的权限的单个用户,并以此用户身份进行连接来执行查询。

  • 不要通过串联涉及用户输入的字符串创建 SQL 语句。相反,创建参数化查询并使用用户输入设置参数值。

  • 如果您必须将用户名和密码存储在某个位置以用作数据库登录凭据,请将它们存储在 Web.config 文件中并使用受保护的配置保护该文件。有关详细信息,请参见使用受保护的配置加密配置信息

有关安全地访问数据的更多信息,请参见 保证数据访问的安全保证 ADO.NET 应用程序的安全

创建安全的错误消息

如果您不小心,恶意用户就可以从应用程序显示的错误消息推断出有关您的应用程序的重要信息。请遵循这些指导:

  • 不要编写会回显可能对恶意用户有用的信息(例如用户名)的错误消息。

  • 将应用程序配置为不向用户显示详细错误。如果为进行调试而要显示详细错误消息,请首先确认该用户是否为 Web 服务器的本地用户。有关详细信息,请参见如何:显示安全错误信息

  • 使用 customErrors 配置元素控制谁可以查看服务器发出的异常。

  • 对于容易发生错误的情况(如数据库访问)创建自定义错误处理方式。有关更多信息,请参见 ASP.NET 页和应用程序中的错误处理

保证敏感信息的安全

敏感信息是任何需要保密的信息。密码或加密密钥即是典型的敏感信息。如果恶意用户可以获得敏感信息,则该信息保护的数据将受到威胁。请遵循这些指导:

  • 如果您的应用程序在浏览器和服务器之间传输敏感信息,请考虑使用安全套接字层 (SSL)。有关如何使用 SSL 保护站点的详细信息,请参见位于 https://support.microsoft.com 上的 Microsoft 知识库中的文章 Q307267“HOW TO: Secure XML Web Services with Secure Socket Layer in Windows 2000”(如何:在 Windows 2000 中使用安全套接字层确保 XML Web 服务的安全)。

  • 使用受保护的配置来确保配置文件(如 Web.config 或 Machine.config 文件)中敏感信息的安全。有关更多信息,请参见使用受保护的配置加密配置信息

  • 如果您必须存储敏感信息,那么即使是使用您认为人们将无法看到它的形式(例如在服务器代码中)进行保存,也不要将它保存在网页中。

  • 使用 System.Security.Cryptography 命名空间中提供的强加密算法。

Cookie 是一种有用的让用户特定的信息保持可用的方法。但是,由于 Cookie 会被发送到浏览器所在的计算机,因此它们容易被假冒或用于其他恶意用途。请遵循这些指导:

  • 不要将任何关键信息存储在 Cookie 中。例如,不要将用户的密码存储在 Cookie 中,即使是暂时存储也不要这样做。通常,不要将任何信息保存在 Cookie 中,因为一旦它被假冒,就会危及您的应用程序的安全。而是在 Cookie 中保存对信息在服务器上的位置的引用。

  • 将 Cookie 的过期日期设置为可接受的最短实际时间。尽可能避免使用永久 Cookie。

  • 考虑对 Cookie 中的信息加密。

  • 考虑将 Cookie 的 SecureHttpOnly 属性设置为 true。

防止拒绝服务威胁

恶意用户危害您的应用程序的一种间接方式是使其不可用。恶意用户可以使应用程序太忙而无法为其他用户提供服务,或者仅仅导致应用程序崩溃。请遵循这些指导:

  • 使用错误处理(例如,try-catch)。包含 finally 块,以便万一失败就可以在其中释放资源。

  • 将 IIS 配置为使用进程调节,这样可以防止应用程序消耗过多的 CPU 时间。

  • 在使用或存储用户输入之前,测试它的大小限制。

  • 对数据库查询的大小加以限制以确保安全。例如,在 ASP.NET 网页中显示查询结果之前,请确保包含的记录数是合理的。

  • 如果文件上载是您的应用程序的一部分,则对它们的大小加以限制。您可以使用类似如下的语法在 Web.config 文件中设置限制(其中 maxRequestLength 值以千字节为单位):

    <configuration>
       <system.web>
            <httpRuntime maxRequestLength="4096" />
       </system.web>
    </configuration>
    

    还可以使用 RequestLengthDiskThreshold 属性来减少大型上载和窗体发布所需的内存开销。

请参见

概念

Web 应用程序安全威胁概述