65.9K
CodeProject 正在变化。 阅读更多。
Home

Web.config 文件中排名前 10 的应用程序安全漏洞 - 第二部分

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (18投票s)

2007 年 5 月 22 日

CPOL

10分钟阅读

viewsIcon

65993

在本篇两部分系列文章的第二部分中,您将了解与身份验证和授权相关的应用程序安全问题,以及在 ASP.NET 基于 Web 的应用程序中常见的五种漏洞。

引言

ASP.NET 基于 Web 的应用程序中最常见且最危险的应用程序安全漏洞,并非来自构成其页面和服务方法的 C# 或 VB.NET 代码,而是来自构成其Web.config文件的 XML 代码。不正确的配置可能导致 Web 站点暴露于应用程序安全漏洞,例如会话劫持、跨站脚本攻击,甚至允许攻击者窃取私人数据。

另一个问题是,Web.config文件被设计成可以随时更改,即使在 Web 应用程序上线后也是如此。一位好意的系统管理员只需修改配置文件,就可能无意中绕过应用程序安全措施,从而使 Web 站点面临攻击。由于 .NET 配置文件以分层方式运行,对全局Machine.config文件进行的任何更改都可能影响整个网络上的所有 Web 站点。

本文的第一部分列出了适用于任何 ASP.NET 基于 Web 的应用程序的最严重的五种配置漏洞。本文将重点介绍身份验证和授权应用程序安全问题,并详细介绍在 ASP.NET 基于 Web 的应用程序中使用窗体身份验证时常见的另外五种漏洞。还将提供一些应用程序安全最佳实践,包括锁定配置文件以确保它们不会被好心(但不知情)的程序员或管理员意外修改。

6. 启用了无 Cookie 身份验证

就像第一部分中讨论的“启用了无 Cookie 会话状态”漏洞一样,在您的 Web 应用程序中启用无 Cookie 身份验证可能导致会话劫持和应用程序安全问题。

易受攻击的配置
<configuration>
 <system.web> 
   <authentication mode="Forms"> 
   <forms cookieless="UseUri"> 
    Secure configuration: 
   <configuration> 
 <system.web> 
<authentication mode="Forms"> 
<forms cookieless="UseCookies">

当会话或身份验证令牌出现在请求 URL 中而不是安全 Cookie 中时,拥有网络监视工具的攻击者就可以绕过应用程序安全,轻松接管该会话,并有效地冒充合法用户。然而,对于经过身份验证的用户,会话劫持对应用程序安全的影响更为严重。例如,在线购物网站通常使用基于 Web 的应用程序,允许用户浏览而无需提供 ID 和密码。但是,当用户准备购买或想查看其订单状态时,他们必须登录并由系统进行身份验证。登录后,网站将提供对更敏感数据的访问权限,例如用户的订单历史记录、账单地址和信用卡号。在身份验证前劫持用户会话的攻击者通常无法获得太多有用信息。但如果攻击者在身份验证之后劫持会话,所有这些敏感信息都可能被泄露。

防止通过 Web 应用程序进行会话劫持的最佳方法是禁用无 Cookie 身份验证,并强制使用 Cookie 来存储身份验证令牌。此应用程序安全措施通过将 `forms` 元素的 `cookieless` 属性更改为 `UseCookies` 值来添加。

7. 未要求身份验证 Cookie 使用 SSL

基于 Web 的应用程序使用安全套接层 (SSL) 协议来加密在 Web 服务器和客户端之间传输的数据。使用 SSL 进行应用程序安全意味着使用网络嗅探器的攻击者将无法解析交换的数据。他们看到的将不是纯文本请求和响应,而是一团乱码,无法理解。

您可以通过将 `forms` 元素的 `requireSSL` 属性设置为 `true` 来要求您的 Web 应用程序的窗体身份验证 Cookie 使用 SSL。

易受攻击的配置
<configuration> 
 <system.web>
  <authentication mode="Forms"> 
  <forms requireSSL="false"> 
    Secure configuration: 
  <configuration> 
 <system.web> 
<authentication mode="Forms"> 
<forms requireSSL="true">

上一节讨论了将身份验证令牌存储在 Cookie 中而不是将其嵌入请求 URL 的重要性。但是,禁用无 Cookie 身份验证只是保护身份验证令牌的第一步。除非发送到 Web 服务器的请求经过加密,否则网络嗅探器仍然可以从请求 Cookie 中读取身份验证令牌。攻击者仍然可以劫持用户的会话。

此时,您可能会想,为什么在应用程序安全方面禁用无 Cookie 身份验证是必要的,因为它对于不接受 Cookie 的用户来说非常不方便,而且请求仍需要通过 SSL 发送。答案是,即使通过 SSL 发送,请求 URL 通常也会被持久化。大多数主要浏览器都会在浏览器历史记录缓存中保存完整的 URL。如果历史记录缓存被泄露,用户的登录凭据也会被泄露。因此,要真正保护身份验证令牌,您必须要求身份验证令牌存储在 Cookie 中,并使用 SSL 来确保 Cookie 安全传输。

通过将 `forms` 元素的 `requireSSL` 属性设置为 `true`,ASP.NET 基于 Web 的应用程序在将身份验证 Cookie 传输到 Web 服务器时将使用安全连接。请注意,IIS 需要额外的配置步骤才能支持 SSL。您可以在 MSDN 上找到配置 IIS SSL 的说明( http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/56bdf977-14f8-4867-9c51-34c346d48b04.mspx?mfr=true)。

8. 使用了滑动过期

所有经过身份验证的 ASP.NET 会话都有一个超时间隔来保护应用程序安全。默认超时值为 30 分钟。因此,用户登录其中一个基于 Web 的应用程序 30 分钟后,他将自动退出登录,并被强制重新验证其凭据。

易受攻击的配置
<configuration> 
 <system.web> 
  <authentication mode="Forms"> 
  <forms slidingExpiration="true"> 
    Secure configuration: 
  <configuration> 
 <system.web> 
<authentication mode="Forms"> 
<forms slidingExpiration="false"> 

`slidingExpiration` 设置是一项应用程序安全措施,用于降低身份验证令牌被盗时对基于 Web 的应用程序的风险。当设置为 `false` 时,指定的超时间隔成为自初始登录以来的固定时间段,而不是不活动的时期。使用被盗身份验证令牌的攻击者最多只有指定的时间长度来冒充用户,然后会话才会超时。由于这些基于 Web 的应用程序的典型攻击者只有令牌,并且不真正知道用户的凭据,因此他们无法以合法用户的身份重新登录,被盗的身份验证令牌现在变得无用,应用程序安全威胁也得到缓解。当启用了滑动过期时,只要攻击者每 15 分钟(或超时间隔的一半)至少向系统发出一次请求,会话就会无限期地保持打开状态。这为攻击者提供了更多窃取信息和在基于 Web 的应用程序中造成其他麻烦的机会。

为了完全避免此应用程序安全问题,您可以通过将 `forms` 元素的 `slidingExpiration` 属性设置为 `false` 来禁用滑动过期。

9. 使用了非唯一身份验证 Cookie

在前面的几节中,我希望我已成功证明了应用程序安全以及将应用程序的身份验证令牌存储在安全 Cookie 值中的重要性。但是 Cookie 不仅仅是一个值;它是一个名称-值对。奇怪的是,不恰当的 Cookie 名称选择会造成与不恰当的存储位置选择一样危险的应用程序安全漏洞。

易受攻击的配置
<configuration>
  <system.web> 
   <authentication mode="Forms"> 
   <forms name=".ASPXAUTH"> 
     Secure configuration: 
   <configuration> 
  <system.web> 
<authentication mode="Forms"> 
<forms name="{abcd1234…}">

身份验证 Cookie 名称的默认值为.ASPXAUTH。如果您的服务器上只有一个基于 Web 的应用程序,那么.ASPXAUTH是 Cookie 名称的一个完美安全的选择。事实上,任何选择都是安全的。但是,当您的服务器运行多个 ASP.NET 基于 Web 的应用程序时,为每个应用程序分配一个唯一的身份验证 Cookie 名称就变得至关重要。如果名称不唯一,那么登录任何基于 Web 的应用程序的用户可能会无意中获得访问所有这些应用程序的权限。例如,登录在线购物网站查看其订单历史记录的用户可能会发现他现在能够访问同一网站上的管理应用程序并更改其购物车中商品的價格。

确保服务器上的所有基于 Web 的应用程序都有自己的授权用户集的方法是,将身份验证 Cookie 名称更改为唯一值。全局唯一标识符 (GUID) 是应用程序安全性的绝佳选择,因为它们保证是唯一的。Microsoft Visual Studio 提供了一个有用的工具,可以自动为您生成 GUID。您可以在“工具”菜单中找到该工具,命令名称为“创建 GUID”。将生成的 GUID 复制到配置文件中 `forms` 元素的 `name` 属性。

10. 使用了硬编码的凭据

易受攻击的配置
<configuration> 
  <system.web> 
    <authentication mode="Forms"> 
    <forms> 
     <credentials> 
     ... 
    </credentials> 
   </forms> 
     Secure configuration: 
   <configuration> 
 <system.web> 
<authentication mode="Forms"> 
<forms> 
</forms>

创建软件的一个基本困难是,应用程序将部署的环境通常与其创建的环境不同。在生产环境中,操作系统可能不同,应用程序运行的硬件可能更强大或更不强大,并且测试数据库将被实时数据库取代。这对于创建需要身份验证的基于 Web 的应用程序是一个问题,因为开发人员和管理员经常使用测试凭据来测试应用程序安全。这引出了一个问题:测试凭据从何而来?

为了方便起见,避免开发人员花费时间创建仅用于测试目的(随后将在应用程序上线生产时丢弃)的凭据存储,Microsoft 在Web.config文件中添加了一个部分,您可以使用它来快速向基于 Web 的应用程序添加测试用户。对于每个测试用户,开发人员会向配置文件添加一个具有所需用户 ID 和密码的元素,如下所示。

<authentication mode="Forms">
 <forms> 
  <credentials> 
  <user name="bob" password="bob"/> 
  <user name="jane" password="Elvis"/> 
  </credentials> 
 </forms> 
</authentication>

虽然对于开发目的来说不可否认地方便,但它从未打算用于生产环境。在配置文件中以纯文本形式存储登录凭据根本不安全。任何具有对Web.config文件读取访问权限的人都可以访问已通过身份验证的 Web 应用程序。可以存储密码值的 SHA-1 或 MD5 哈希值,而不是以纯文本形式存储密码。这稍微好一些,但仍然不是一个安全的解决方案。使用此方法,用户名仍然没有加密。首先,向潜在攻击者提供已知的用户名可以更容易地对系统执行暴力破解攻击。其次,Internet 上有许多 SHA-1 和 MD5 哈希值的反向查找数据库。如果密码很简单,例如字典中的单词,那么几乎可以保证在这些哈希字典之一中找到它。

存储登录凭据的最安全方法是不要将其存储在配置文件中。在生产应用程序中,请从您的Web.config文件中删除 `credentials` 元素。

您尚未完全脱险

现在您已读完前十名列表,并检查了您的配置设置,您的应用程序将永远安全,对吗?还为时过早。Web.config文件以分层继承方式运行。每个Web.config文件都继承自父目录中的任何Web.config文件。该Web.config文件又从其父目录中的任何Web.config文件继承值,依此类推。系统上的所有Web.config文件都从位于 .NET 框架目录中的全局配置文件Machine.config继承。其效果是,您的应用程序的运行时行为可以通过修改更高目录中的配置文件来改变。

这有时会产生意想不到的后果。系统管理员可能会响应一个完全不同的应用程序的问题而修改配置文件,但该更改可能会在您的应用程序中产生安全漏洞。例如,用户可能会报告他无法在浏览器中启用 Cookie 而访问该应用程序。管理员试图提供帮助,修改了全局配置文件,为所有应用程序允许无 Cookie 身份验证。

为了防止应用程序特定设置被意外修改,解决方案是永远不要依赖默认设置值。例如,调试在配置文件中默认是禁用的。如果您正在检查您应用程序的配置文件,并且注意到 debug 属性为空,您可能会假设调试已禁用。但是,它可能已禁用,也可能未禁用——应用的值取决于系统中父配置设置的值。最安全的选择是始终在您的应用程序的配置中明确设置与安全相关的参数。

最终,保护 Web 应用程序需要 QA 到安全运营的许多不同团队的努力和勤奋。然而,编写应用程序本身的开发人员有责任从开发过程开始就将安全性融入应用程序。通过从一开始就做出注重安全的决定,开发人员可以创建用户可以信任其机密信息的应用程序,并且能够抵御黑客发起的攻击。正如我在这里试图展示的,有时这个过程可能与在配置应用程序时做出正确的决定一样简单。

© . All rights reserved.