Web.config 文件中的十大应用程序安全漏洞 - 第一部分






4.15/5 (25投票s)
在本篇文章的上半部分,您将了解到导致 ASP.NET Web 应用程序出现整体问题的五种应用程序安全配置错误,它们是十大“最严重”的配置错误之一。了解如何保护 ASP.NET 应用程序的 Web.config 文件。
引言
如今,组织网络安全的最大威胁来自于其公开的网站以及网站上的 Web 应用程序。与数据库等只能通过防火墙与外部隔离开的内部专有网络服务不同,公开的网站通常是任何人都可以访问的,因此应用程序安全问题尤为突出。随着网络安全性的提高,Web 应用程序中的漏洞不可避免地引起了黑客(无论是出于商业目的还是娱乐目的)的注意,他们已经开发出了利用这些漏洞的技术。事实上,针对 Web 应用程序层的攻击现在已经超过了在网络层进行的攻击,并且可能造成同样严重的后果。
一些有远见的软件架构师和开发人员正在了解这些应用程序安全威胁,并在设计 Web 应用程序时就考虑了安全性。通过在开发过程的早期就“内嵌”应用程序安全性,而不是在最后才“修补”,您更有可能创建能够抵御黑客攻击的安全应用程序。然而,即使是最细致、最注重安全的 C# 或 VB.NET 代码,如果您忽视了保护应用程序的 Web.config 配置文件,仍然可能容易受到攻击。配置不正确的 Web 应用程序可能和编码不正确的应用程序一样危险。更糟糕的是,许多配置设置实际上 默认 就是不安全的。
本文列出了五种普遍存在于所有 ASP.NET Web 应用程序中的应用程序安全配置错误,它们是“最严重”的。本文的第二部分将列出另外五种专门适用于使用 Web Forms 身份验证的 ASP.NET 站点的配置错误。那么,闲话少说,让我们开始吧!
1. 定制错误信息禁用
当您禁用定制错误信息(如下所示)时,ASP.NET 默认会向客户端显示详细的错误消息。
<configuration>
<system.web>
<customErrors mode="Off">
<configuration>
<system.web>
<customErrors mode="RemoteOnly">
仅凭错误来源本身,可能看起来并不对应用程序安全构成风险,但请考虑一下:黑客能够收集到关于网站的信息越多,他们成功攻击该网站的可能性就越大。错误消息对攻击者来说可能是一座信息金矿。默认的 ASP.NET 错误消息会列出 Web 服务器使用的 ASP.NET 和 .NET 框架的具体版本,以及抛出的异常类型。仅仅知道使用了哪些 Web 应用程序(在本例中是 ASP.NET)就会损害应用程序的安全性,因为它告诉攻击者服务器运行的是一个相对较新的 Microsoft Windows 版本,并且 Microsoft Internet Information Server (IIS) 6.0 或更高版本被用作 Web 服务器。异常的类型也可能帮助攻击者分析 Web 应用程序;例如,如果抛出了“SqlException
”,那么攻击者就知道该应用程序正在使用某个版本的 Microsoft SQL Server。
您可以通过将 <customErrors>
元素的 mode
属性修改为 “On
” 或 “RemoteOnly
” 来构建应用程序安全性,以防止此类信息泄露。此设置指示 Web 应用程序在生成未处理的异常时显示一个不显眼、通用的错误消息。另一种规避此应用程序安全问题的方法是通过设置 <customErrors>
元素的 “defaultRedirect
” 属性,在发生错误时将用户重定向到一个新页面。这种方法可以提供更好的应用程序安全性,因为默认的通用错误页面仍然泄露了过多的系统信息(即它正在使用 Web.config 文件,这表明服务器正在运行 ASP.NET)。
2. 在 Web 应用程序中保留跟踪功能已启用
ASP.NET 的跟踪功能是确保应用程序安全性的最有用工具之一,可用于调试和分析 Web 应用程序。不幸的是,如果它在生产环境中保持启用状态,那么它也是黑客可以用来攻击您的 Web 应用程序的最有用的工具之一。
<configuration>
<system.web>
<trace enabled="true" localOnly="false">
<configuration>
<system.web>
<trace enabled="false" localOnly="true">
当 <trace>
元素对 Web 应用程序的远程用户启用时(localOnly="false"
),任何用户只需浏览到 “trace.axd” 页面即可查看应用程序最近请求的非常详细的列表。如果详细的异常消息对试图规避应用程序安全的黑客来说是金矿,那么跟踪日志就相当于金库!跟踪日志提供了大量信息:服务器运行的 .NET 和 ASP.NET 版本、请求引起的页面方法的所有完整跟踪(包括执行时间)、会话状态和应用程序状态键、请求和响应 Cookie、完整的请求头、窗体变量和 QueryString 变量,最后还有完整的服务器变量集。
试图绕过应用程序安全的黑客显然会发现窗体变量历史记录很有用,因为其中可能包含可以收集并出售给垃圾邮件发送者的电子邮件地址、可用于冒充用户的 ID 和密码,或者信用卡和银行账号。即使是跟踪集合中最不起眼的数据,在不怀好意的人手中也可能很危险。例如,“APPL_PHYSICAL_PATH
” 服务器变量包含 Web 应用程序在服务器上的物理路径,这可能有助于攻击者对系统进行目录遍历攻击。
防止黑客从 Web 应用程序获取跟踪数据的最佳方法是通过将 <trace>
元素的 “enabled
” 属性设置为 “false
” 来完全禁用跟踪查看器。如果您必须启用跟踪查看器,无论是为了调试还是分析您的应用程序,请务必将 <trace>
元素的 “localOnly
” 属性设置为 “true
”。这允许用户仅从 Web 服务器访问跟踪查看器,并禁用从任何远程机器查看它,从而提高您的应用程序安全性。
3. 调试已启用
在调试模式下部署 Web 应用程序是一个非常常见的错误。几乎所有的 Web 应用程序都需要一些调试。Visual Studio 2005 在您开始调试应用程序时,甚至会自动修改 Web.config 文件以允许调试。而且,由于部署 ASP.NET 应用程序就像将文件从开发文件夹复制到部署文件夹一样简单,因此很容易看到开发配置设置如何意外地进入生产环境,从而损害应用程序的安全性。
<configuration>
<system.web>
<compilation debug="true">
<configuration>
<system.web>
<compilation debug="false">
与本文中描述的前两个应用程序安全漏洞一样,启用调试很危险,因为您正在向不应访问它的最终用户提供内部信息,他们可能会利用这些信息来攻击您的 Web 应用程序。例如,如果您在应用程序中启用了调试并禁用了定制错误信息,那么显示给 Web 应用程序最终用户的任何错误消息都将不仅包含服务器信息、详细的异常消息和堆栈跟踪,还包括错误发生页面的实际源代码。
不幸的是,此配置设置不是源代码可能显示给用户的唯一方式。这是一个说明为什么开发人员不应仅专注于一种配置设置来提高应用程序安全性的故事。在 Microsoft ASP.NET AJAX 框架的早期版本中,当发生异常时,某些控件会将堆栈跟踪和源代码返回到客户端浏览器。无论配置中的定制错误设置如何,当启用调试时,都会发生此行为。因此,即使您已正确配置 Web 应用程序以在发生错误时显示非描述性消息,但如果您忘记禁用调试,仍然可能会意外地向最终用户泄露您的源代码。
要禁用调试,请将 <compilation>
元素的 “debug
” 属性值设置为 “false
”。这是该设置的默认值,但正如我们在本文的第二部分将看到的,明确设置所需的值比依赖默认值来保护应用程序安全性更安全。
4. 客户端脚本可访问 Cookie
在 Internet Explorer 6.0 中,Microsoft 引入了一个名为 “HttpOnly
” 的新 Cookie 属性。虽然您可以按每个 Cookie 的基础以编程方式设置该属性,但也可以在站点配置中全局设置。
<configuration>
<system.web>
<httpCookies httpOnlyCookies="false">
<configuration>
<system.web>
<httpCookies httpOnlyCookies="true">
具有此属性标记的任何 Cookie 都只能从服务器端代码访问,而不能被任何客户端脚本代码(如 JavaScript 或 VBScript)访问。这种将 Cookie 与客户端隔离有助于保护 Web 应用程序免受跨站脚本攻击。黑客通过尝试将自己的脚本代码插入 Web 页面来绕过任何已有的应用程序安全措施,从而发起跨站脚本(也称为 CSS 或 XSS)攻击。任何接受用户输入并将其回显的页面都有可能存在漏洞。例如,一个提示输入用户名和密码,并在成功登录后显示“欢迎回来,<用户名>”的登录页面,可能容易受到 XSS 攻击。
消息板、论坛和 Wiki 也经常容易出现应用程序安全问题。在这些网站上,合法用户会发布他们的想法或意见,这些想法或意见对所有其他访问者都是可见的。但是,攻击者不会发布关于当前主题的内容,而是会发布类似 “<script>alert(document.cookie);</script>
” 的消息。消息板现在会在其页面代码中包含攻击者的脚本代码,然后浏览器会对其进行解释并为未来的网站访问者执行。通常,攻击者会使用此类脚本代码来尝试获取用户的身份验证令牌(通常存储在 Cookie 中),他们可以使用该令牌来冒充用户。当 Cookie 被标记为 “HttpOnly
” 属性时,其值对客户端是隐藏的,因此此攻击将失败。
如前所述,可以通过将 “HttpCookie
” 对象的 “HttpOnly
” 属性设置为 “true
” 来以编程方式为任何单个 Cookie 启用 “HttpOnly
”。然而,更简单、更可靠的方法是配置应用程序以自动为所有 Cookie 启用 “HttpOnly
”。为此,请将 <httpCookies>
元素的 “httpOnlyCookies
” 属性设置为 “true
”。
5. 无 Cookie 会话状态已启用
在 ASP.NET 的初始 1.0 版本中,当您的 Web 应用程序需要维护会话状态时,您在如何传输会话令牌方面别无选择:它始终存储在 Cookie 中。不幸的是,这意味着不接受 Cookie 的用户无法使用您的应用程序。因此,在 ASP.NET 1.1 中,Microsoft 添加了通过使用 “cookieless
” 设置来支持无 Cookie 会话令牌。
<configuration>
<system.web>
<sessionState cookieless="UseUri">
<configuration>
<system.web>
<sessionState cookieless="UseCookies">
配置为使用无 Cookie 会话状态的 Web 应用程序现在会将会话令牌存储在页面 URL 中,而不是 Cookie 中。例如,页面 URL 可能从 http://myserver/MyApplication/default.aspx 变为 http://myserver/MyApplication/(123456789ABCDEFG)/default.aspx。在此示例中,“123456789ABCDEFG” 代表当前用户的会话令牌。同时浏览该网站的其他用户将收到一个完全不同的会话令牌,从而导致一个不同的 URL,例如 http://myserver/MyApplication/(ZYXWVU987654321)/default.aspx。
虽然添加对无 Cookie 会话状态的支持确实提高了 ASP.NET Web 应用程序对不接受 Cookie 的用户的可用性,但它也带来了使这些应用程序更容易受到会话劫持攻击的副作用。会话劫持基本上是一种身份盗窃形式,黑客通过窃取用户的会话令牌来冒充合法用户。当会话令牌存储在 Cookie 中,并且请求是通过安全通道(即使用 SSL)进行的,则令牌是安全的。然而,当会话令牌包含在 URL 中时,黑客更容易找到并窃取它。通过使用网络监控工具(也称为“嗅探器”)或获取最近的请求日志,劫持用户会话变得很容易,只需浏览到包含被盗的唯一会话令牌的 URL 即可。Web 应用程序无法知道这个带有会话令牌“123456789ABCDEFG”的新请求不是来自原始的合法用户。它会愉快地加载相应的会话状态并将响应返回给黑客,黑客现在有效地冒充了用户。
防止这些会话劫持攻击最有效的方法是强制您的 Web 应用程序使用 Cookie 来存储会话令牌。这是通过将 <sessionState>
元素的 “cookieless
” 属性设置为 “UseCookies
” 或 “false
” 来实现的。但是那些不接受 Cookie 的用户呢?您是否必须在让所有用户都能访问您的应用程序与确保所有用户都能安全地使用您的应用程序之间做出选择?在 ASP.NET 2.0 中,这两种情况可以兼顾。通过将 “cookieless
” 属性设置为 “AutoDetect
”,应用程序将为接受 Cookie 的用户在 Cookie 中存储会话令牌,为不接受 Cookie 的用户在 URL 中存储。这意味着只有使用无 Cookie 令牌的用户仍然容易受到会话劫持的攻击。考虑到另一种选择——拒绝 Cookie 的用户根本无法使用该应用程序——这通常是可以接受的。讽刺的是,许多用户因为隐私原因禁用 Cookie,而这样做实际上可能使他们更容易受到攻击。
间歇
我们在本文中讨论的前五个 Web.config 漏洞适用于所有 ASP.NET Web 应用程序,无论其身份验证方法如何,甚至是否使用身份验证。本文的第二部分将详细介绍另外五种仅适用于使用 Forms 身份验证的应用程序的漏洞。这些配置错误可能比前五个更危险,它们能让入侵者访问您网站上本应安全区域。最后,我们还将讨论一些锁定配置文件的锁定方法,以防止它们被意外修改。