Username: Password:

利用 ASP.NET 的内置功能抵御 Web 攻击
来源:作者:yjz0065 发布时间:2007-11-21 13:26:00

假如您正在阅读本文,可能就无需再向您灌输 Web 应用程式中的安全性愈来愈重要这一事实了。您需要的可能是一些有关怎样在 ASP.NET 应用程式中实现安全性的实际建议。坏消息是,没有任何研发平台 ? 包括 ASP.NET在内 ? 能够确保一旦采用了该平台,您就能够编写百分百安全的代码。谁要是这么说,一准在撒谎。好消息是,就 ASP.NET 来说,ASP.NET,特别是版本 1.1 和即将发行的版本 2.0,整合了一些便于使用的内置防御屏障。

光是应用任何这些功能并不足以保护 Web 应用程式,使其免受任何可能和可预见的攻击。但是,假如和其他防御技巧和安全策略相结合,内置的 ASP.NET 功能将能够构成一个强大的工具包,有助于确保应用程式在安全的环境中运行。

Web 安全性是各种因素的总和,是一种范围远超单个应用程式的策略的结果,这种策略涉及数据库管理、网路配置,连同社会工程和 phishing。

本文的目的在于说明 ASP.NET 研发人员为了将安全标准保持到合理的高度,所应始终坚持的做法。这也就是安全性最主要的内容:保持警惕,永不完全放松,让坏人越来越难以发起黑客攻击。

下面我们来看看 ASP.NET 提供了哪些能够简化这项工作的功能。

威胁的来源

在表 1 中,我汇总了最常见的 Web 攻击类型,连同应用程式中可能导致这些攻击得手的缺陷。

攻击 攻击的可能发起人

跨站点脚本 (XSS)

回显到页的不可信用户输入

SQL 注入

串连用户输入以形成 SQL 命令

会话劫持

会话 ID 猜测和失窃的会话 ID Cookie

一次单击

通过脚本发送的未被察觉的 HTTP 张贴

隐藏域篡改

未检查(且受信)的隐藏域被填充以敏感数据

表 1. 常见的 Web 攻击

列表中显现出来的关键性事实有哪些?在我看来,起码有以下三点:

无论您何时将何种用户输入插入浏览器的标记中,您都潜在地将自己暴露在了代码注入攻击(任何 SQL 注入和 XSS 变种)之下。

必须以安全的方式实现数据库访问,就是说,应当为数据库使用尽可能少的权限,并通过角色来划分各个用户的职责。

永远都不通过网络发送敏感数据(更别说是明文了),并且必须以安全的方式将敏感数据存储在服务器上。

有意思的是,上面的三点分别针对的是 Web 安全性的三个不同方面,而这三个方面结合起来,才是唯一的一种生成防攻击、防篡改应用程式的合理方式。Web 安全性的各个层面能够总结如下:

编码实践:数据验证、类型和缓冲区长度检查,防篡改措施

数据访问策略:使用决策来保护可能最弱的帐户,使用存储过程或至少是参数化的命令。

有效的存储和管理:不将关键性数据发送到客户端,使用哈希代码来检测操作,对用户进行身份验证并保护标识,应用严格的密码策略

如您所看到的,只有能够通过研发人员、架构师和管理员的一起努力,才能够产生安全的应用程式。请不要假定您能够以其他方式达到同样目的。

编写 ASP.NET 应用程式时,您并不是独自面对黑客大军:唯一的武器是通过自己的大脑、技能和手指键入的代码行。ASP.NET 1.1 和更高版本都会施加援手,他们具备一些特定的功能,能够自动提高防御以上列出的某些威胁的屏障。下面我们对他们进行周详的检视。

ViewStateUserKey

从 ASP.NET 1.1 开始引入,ViewStateUserKeyPage 类的一个字符串属性,只有很少数研发人员真正熟悉该属性。为什么呢?让我们看看文档中是怎么说的。

在和当前页相关联的视图状态变量中将一个标识符分配给单个用户

除了有些累赘,这个句子的意思相当清楚;但是,您能老老实实地告诉我,他说明了该属性原本的用途吗?要理解 ViewStateUserKey 的角色,您需要继续往下读,直到 Remarks 部分。

该属性有助于防止一次单击攻击,因为他提供了附加的输入以创建防止视图状态被篡改的哈希值。换句话说,ViewStateUserKey 使得黑客使用客户端视图状态的内容来准备针对站点的恶意张贴困难了许多。能够为该属性分配任何非空的字符串,但最好是会话 ID 或用户的 ID。为了更好地理解这个属性的重要性,下面我们简短介绍一下一次单击攻击的基本知识。

一次单击攻击包括将恶意的 HTTP 表单张贴到已知的、易受攻击的 Web 站点。之所以称为“一次单击”,是因为他通常是以受害者不经意的单击通过电子邮件发送的或在拥挤的论坛中浏览时发现的诱惑性链接而开始的。通过点击该链接,用户无意中触发了一个远程进程,最终导致将恶意的

提交到一个站点。大家都坦白些吧:您真能告诉我,您从未因为好奇而单击过 Click here to win $1,000,000 这样的链接吗?显然,并没有什么糟糕的事情发生在您身上。让我们假定的确是这样的;您能说 Web 社区中的任何其他人都幸免于难了吗?谁知道呢。

要想成功,一次单击攻击需要特定的背景条件:

攻击者必须充分了解该有漏洞的站点。这是可能的,因为攻击者能够“勤奋地”研究该文档,或他/她是一位愤怒的内部人员(例如,被解雇而又不诚实的雇员)。因此,这种攻击的后果可能是极其严重的。

站点必须是使用 Cookie(假如是持续性 Cookie,效果更好)来实现单次登录,而攻击者曾收到过有效的身份验证 cookie。

该站点的某些用户进行了敏感的事务。

攻击者必须能够访问目标页。

前已提及,攻击包括将恶意的 HTTP 表单提交到等待表单的页。能够推知,该页将使用张贴来的数据执行某些敏感操作。可想而知,攻击者清楚地了解怎样使用各个域,并能够想出一些虚假的值来达到他的目的。这通常是目标特定的攻击,而且由于他所建立的三角关系,很难追本溯源 ? 即黑客诱使受害者单击该黑客站点上的一个链接,而这又会导致恶意代码被张贴到第三个站点。(请参阅图 1。)


图 1. 一次单击攻击

为什么是不抱怀疑的受害者?这是因为,这种情况下,服务器日志中所显示的发出恶意请求的 IP 地址,是该受害者的 IP 地址。如前所述,这种工具并不像“经典”的 XSS 相同常见(和易于发起);但是,他的性质决定了他的后果可能是灾难性。怎样应对他?下面,我们审视一下这种攻击在 ASP.NET 环境下的工作机理。

除非操作编码在 Page_Load 事件中,否则 ASP.NET 页根本不可能在回发事件之外执行敏感代码。要使回发事件发生,视图状态域是必需的。请牢记,ASP.NET 会检查请求的回发状态,并根据是否存在 _VIEWSTATE 输入域,相应地配置 IsPostBack。因此,无论谁要向 ASP.NET 页发送虚假请求,都必须提供一个有效的视图状态域。

一次单击攻击要想得手,黑客必须能够访问该页。此时,有远见的黑客会在本地保存该页。这样,他/她就能够访问 _VIEWSTATE 域并使用该域,用旧的视图状态和其他域中的恶意值创建请求。问题是,这能行吗?

为什么不能?假如攻击者能够提供有效的身份验证 cookie,黑客就能够进入,请求将被照常处理。服务器上根本不会检查视图状态内容(当 EnableViewStataMac 为 off 时),或只会检查是否被篡改过。默认情况下,试图状态中没有机制能够将该内容和特定的用户关联起来。攻击者能够轻松地重用所获取的视图状态,冒充另一个用户合法地访问该页,以生成虚假请求。这正是 ViewStateUserKey 介入的地方。

假如选择准确,该属性能够将用户特定的信息添加到视图状态。处理请求时,ASP.NET 会从视图状态中提取秘钥,并将其和正在运行的页的 ViewStateUserKey 进行比较。假如两者匹配,请求将被认为是合法的;否则将引发异常。对于该属性,什么值是有效的?

为任何用户将 ViewStateUserKey 配置为常量字符串,相当于将他保留为空。您必须将他配置为对各个用户都不同的值 ? 用户 ID,会话 ID 更好些。由于一些技术和社会原因,会话 ID 更为合适,因为会话 ID 不可预测,会超时失效,并且对于每个用户都是不同的。

以下是一些在您的任何页中都必不可少的代码:

void Page_Init (object sender, EventArgs e) {
   ViewStateUserKey = Session.SessionID;
   :
}

为了避免重复编写这些代码,您能够将他们固定在从 Page 派生的类的 OnInit 虚拟方法中。(请注意,您必须在 Page.Init 事件中配置此属性。)

protected override OnInit(EventArgs e) {
   base.OnInit(e); 
   ViewStateUserKey = Session.SessionID;
}

总体说来,使用基 page 类始终都不失为一件好事,我在 Build Your ASP.NET Pages on a Richer Bedrock 一文中已进行了说明。假如您要了解更多有关一次单击攻击者的伎俩的信息,能够在 aspnetpro.com 找到一篇很好的文章。

Cookie 和身份验证

Cookie 之所以存在,是因为他们能够帮助研发人员达到一定目的。Cookie 充当了浏览器和服务器之间的一种持续性链接。特别是对于使用单次登录的应用程式来说,失窃的 cookie 正是使得攻击成为可能的罪魁祸首。这对于一次单击攻击来说一点没错。

要使用 Cookie,无需以编程方式显式创建和读取他们。假如您使用会话状态且实现表单身份验证,您会隐式地使用 Cookie。当然,ASP.NET 支持无 cookie 的会话状态,而且,ASP.NET 2.0 还引入了无 cookie 的表单身份验证。因此,理论上您能够在没有 Cookie 的情况下使用这些功能。我并不是说您不再必须这么做了,但事实上这正是疗法比疾病更糟的情形之一。无 Cookie 的会话,实际上将会话 ID 嵌入了 URL 中,这样谁都能够看到。

和使用 Cookie 有关的潜在问题有哪些?Cookie 可能被盗(即被复制到黑客的电脑)和投毒(即被填充以恶意数据)。这些操作通常是即将发起的攻击的前奏。假如被盗,Cookie 会“授权”外部用户以您的名义连接到应用程式(并使用受保护的页),这可能使黑客轻松地规避授权,并能够执行角色和安全配置所允许受害者执行的任何操作。因此,身份验证 Cookie 通常被赋予相对较短的生存期,即 30 分钟。(请注意,即使浏览器的会话完成所需的时间更长,cookie 仍会过期。)发生失窃时,黑客有 30 分钟的时限来尝试攻击。

能够将这个时限加长,以免用户不得但是于频繁地登录;但请注意,这么做会将您自己置于危险境地。任何情况下,都应避免使用 ASP.NET 持续性 Cookie。他将导致 cookie 具备几乎永久的生存期,最长可达 50 年!下面的代码片段演示了怎样轻松修改 cookie 的过期日期。

void OnLogin(object sender, EventArgs e) {
   // Check credentials
   if (ValidateUser(user, pswd)) {
      // Set the cookie’s expiration date
      HttpCookie cookie;
      cookie = FormsAuthentication.GetAuthCookie(user, isPersistent);
      if (isPersistent) 
         cookie.Expires = DateTime.Now.AddDays(10);

      // Add the cookie to the response
      Response.Cookies.Add(cookie);

      // Redirect
      string targetUrl;
      targetUrl = FormsAuthentication.GetRedirectUrl(user, isPersistent);
   Response.Redirect(targetUrl);
   }
}

您能够在自己的登录表单中使用这些代码来微调身份验证 Cookie 的生存期。

会话劫持

Cookie 还被用于检索特定用户的会话状态。会话的 ID 被存储到 cookie 中,该 cookie 和请求一起来回传送,存储在浏览器的电脑上。同样,假如失窃,会话 cookie 将可被用来使黑客进入系统并访问别人的会话状态。不用说,只要指定的会话处于活动状态(通常不超 20 分钟),这就有可能发生。通过冒充的会话状态发起的攻击称为会话劫持。有关会话劫持的周详信息,请阅读 Theft On The Web: Prevent Session Hijacking

这种攻击有多危险?很难讲。这要取决于 Web 站点的功能,更为重要的是,该站点的页是怎样设计的。例如,假定您能够获得别人的会话 cookie,并将他附加到对站点上某个页的请求中。您加载该页并逐步研究他的普通用户界面。除了该页使用另一个用户的会话状态工作外,您无法将任何代码注入该页,也无法修改该页中的任何内容。这本身并不太坏,但是假如该会话中的信息是敏感和关键性的,就有可能直接导致黑客成功实现利用。黑客无法渗透到会话存储的内容中,但他能够使用其中存储的信息,就像自己是合法进入的相同。例如,假定有这样一个电子商务应用程式,他的用户在浏览站点时将物品添加到购物车中。

方案 1。 购物车的内容存储在会话状态中。但是,在结帐时,用户被需要通过安全的 SSL 连接确认和输入付款周详信息。这种情况下,通过接入其他用户的会话状态,黑客仅能够了解到一些有关受害者的购物喜好的细节。在这种环境下劫持实际上并不会导致任何损害。受威胁的只是保密性。

方案 2。应用程式为每位注册用户处理一份档案,并将档案保存在会话状态中。糟糕的是,档案中(可能)包括信用卡信息。为什么要将用户档案周详信息存储到会话中?可能应用程式的其中一个目标是,从根本上避免使用户不得不重复键入自己的信用卡和银行信息。因此,在结算时,应用程式会将用户定位到一个具备预先填充的域的页。而有失谨慎的是,这些域的其中一个是从会话状态中获取的信用卡号。现在您能够猜到故事的结局了吗?

应用程式的页的设计,是防止会话劫持攻击的关键所在。当然,更有两点没有理清。第一点是,怎样防止 cookie 盗窃?第二点是,ASP.NET 能够怎样检测和阻止劫持?

ASP.NET 会话 cookie 极其简单,仅限于包含会话 ID 字符串本身。ASP.NET 运行库从 cookie 中提取会话 ID,并将其和活动的会话进行比较。假如 ID 有效,ASP.NET 将连接到对应的会话并继续。这种行为极大地方便了已偷到或能够猜出有效的会话 ID 的黑客。

XSS 和中间人 (man-in-the-middle) 攻击连同对客户端 PC 的强力访问,都是获取有效 cookie 的方法。为了防止盗窃,您应当实现安全最好实践来防止 XSS 及其各变种得手。

而为了防止会话 ID 猜测,您应当干脆避免太高估计自己的技能。猜测会话 ID 意味着您知道怎样预测有效的会话 ID 字符串。对于 ASP.NET 所使用的算法(15 个随机数字,映射为启用 URL 的字符),随机猜测到有效 ID 的概率接近于零。我想不到任何理由来用自己的会话 ID 生成器替换默认的会话 ID 生成器。许多情况下,这么做只会为攻击者提供方便。

会话劫持更为糟糕的后果是一旦 cookie 被盗或被猜出,ASP.NET 并没有什么办法来检测欺诈性的 cookie 使用。同样,原因是 ASP.NET 将自己限制为检查 ID 的有效性,连同 cookie 的来源地。

我在 Wintellect 的朋友 Jeff Prosise 为 MSDN Magazine 写了一篇很好的关于会话劫持的文章。他的结论并不令人安慰:几乎不可能建立能够完全抵御依靠偷来的会话 ID Cookie 所发起的攻击的防御工事。但是他研发的代码为进一步提升安全标准提供了很明智的建议。Jeff 创建了一个 HTTP 模块,该模块为会话 ID Cookie 监控传入的请求和传出的响应。该模块将一条哈希代码附加到会话 ID 之后,使攻击者重用 cookie 更为困难。您能够在此处阅读详情。

EnableViewStateMac

视图状态用于在对同一个页的两个连续请求之间保持控件的状态。默认情况下,视图状态是 Base64 编码的,并使用一个哈希值签名,以防止篡改。除非更改默认的页配置,否则不可能篡改视图状态。假如攻击者修改了视图状态,甚至使用正确的算法重新生成了视图状态,ASP.NET 都会捕获这些尝试并引发异常。视图状态被篡改并不一定有害,虽然他修改了服务器控件的状态 ? 但可能成为造成严重感染的工具。因此, 移除默认情况下进行的电脑身份验证代码 (MAC) 交叉检查就异常重要。请参阅图 2。


图 2. 启用 EnableViewStateMac 时,使视图状态本身难以篡改的因素

启用了 MAC 检查时(默认情况),将对序列化的视图状态附加一个哈希值,该值是使用某些服务器端值和视图状态用户秘钥(假如有)生成的。回发视图状态时,将使用新的服务器端值重新计算该哈希值,并将其和存储的值进行比较。假如两者匹配,则允许请求;否则将引发异常。即使假设黑客具备破解和重新生成视图状态的能力,他/她仍需要知道服务器存储的值才能够得出有效的哈希。具体说来,该黑客需要知道 machine.config 的 <machineKey> 项中引用的电脑秘钥。

默认情况下, 项是自动生成的,以物理方式存储在 Windows Local Security Authority (LSA) 中。仅在 Web 场(此时视图状态的电脑秘钥必须在任何的电脑上都相同)的情形下,您才应当在 machine.config 文档中将其指定为明文。

视图状态 MAC 检查是通过一个名为 EnableViewStateMac@Page 指令属性控制的。如前所述,默认情况下,他被配置为 true。请永远不要禁用他;否则将会使视图状态篡改一次单击攻击成为可能,并具备很高的成功概率。

ValidateRequest

跨站点脚本 (XSS) 对于很多经验丰富的 Web 研发人员来说是老朋友了,他在 1999 年左右就已出现了。简单地说,XSS 利用代码中的漏洞来将黑客的可执行代码引入另一个用户的浏览器会话中。假如被执行,注入的代码能够执行多种不同的操作 ? 获取 Cookie 并将一个副本上载到黑客控制的 Web 站点,监控用户的 Web 会话并转发数据,修改被黑的页的行为和外观以使其提供错误的信息,甚至使自己变为持续性的,这样用户下一次返回该页时,欺诈代码会再次运行。请在 TechNet 文章 Cross-site Scripting Overview 中周详阅读有关 XSS 攻击的基础知识。

代码中的哪些漏洞导致 XSS 攻击成为可能?

XSS 利用的是动态生成 HTML 页、但并不验证回显到页的输入的 Web 应用程式。这里的输入 是指查询字符串、Cookie 和表单域的内容。假如这些内容在未经适当性能检查的情况下出现在网络上,就存在黑客对其进行操作以在客户端浏览器中执行恶意脚本的风险。(前面提到的一次单击攻击其实是 XSS 的一种新近变种。)典型的 XSS 攻击会导致不抱怀疑的用户点击一条诱惑性链接,而该链接中嵌入了转义的脚本代码。欺诈代码将被发送到一个存在漏洞且会毫不怀疑地输出他的页。以下是可能发生的情况的一个示例:

Click to claim your prize 

用户单击一个看上去明显安全的链接,最终导致将一些脚本代码传递到存在漏洞的页,这些代码首先获取用户电脑上的任何 Cookie,然后将他们发送到黑客的 Web 站点。

请务必注意,XSS 不是个特定于供给商的问题,因此并不一定会利用 Internet Explorer 中的漏洞。他影响现在市场上的任何 Web 服务器和浏览器。更应注意的是,没有哪一个修补程式能够修复这一问题。您完万能够保护自己的页免受 XSS 攻击,方法是应用特定的措施和合理的编码实践。此外,请注意,攻击者并无需用户单击链接就能够发起攻击。

要防御 XSS,您必须从根本上确定哪些输入是有效的,然后拒绝任何其他输入。您能够在一本书中读到抵御 XSS 攻击的周详检查表,该书在 Microsoft 属于必读范围 ? Writing Secure Code,作者是 Michael Howard 和 David LeBlanc。特别地,我建议您仔细阅读第 13 章。

阻止阴险的 XSS 攻击的主要方法是向您的输入(任何类型的输入数据)添加一个设计合理、有效的验证层。例如,某些情况下即使是原本无害的颜色(RGB 三色)也会将不受控制的脚本直接带入页中。

在 ASP.NET 1.1 中,@Page 指令上的 ValidateRequest 属性被打开后,将检查以确定用户没有在查询字符串、Cookie 或表单域中发送有潜在危险性的 HTML 标记。假如检测到这种情况,将引发异常并中止该请求。该属性默认情况下是打开的;您无需进行任何操作就能够得到保护。假如您想允许 HTML 标记通过,必须主动禁用该属性。

<%@ Page ValidateRequest="false" %> 

ValidateRequest不是 万能的药方,无法替代有效的验证层。请阅读此处以获取大量有关该功能的基础原理的宝贵信息。他基本上通过应用一个正则表达式来捕获一些可能有害的序列。

注 ValidateRequest 功能原本是有缺陷的,因此您需要应用一个修补程式他才能按预期工作。这样的重要信息常常不为人们所注意。奇怪的是,我发现我的其中一台电脑仍受该缺陷的影响。试试看!

没有任何关闭 ValidateRequest 的理由。您能够禁用他,但必须有很好的理由;其中一条这样的理由可能是用户需要能够将某些 HTML 张贴到站点,以便得到更好的格式配置选项。这种情况下,您应当限制所允许的 HTML 标记(



)的数目,并编写一个正则表达式,以确保不会允许或接受任何其他内容。

以下是一些有助于防止 ASP.NET 遭受 XSS 攻击的其他提示:

使用 HttpUtility.HtmlEncode 将危险的符号转换为他们的 HTML 表示形式。

使用双引号而不是单引号,这是因为 HTML 编码仅转义双引号。

强制一个代码页以限制能够使用的字符数。

总之,使用但是不要完全信任 ValidateRequest 属性,不要太过懒惰。花些时间,从根本上理解 XSS 这样的安全威胁,并规划以一个关键点为中央的防御策略:任何的用户输入都是危险的。

数据库角度

SQL 注入是另一种广为人知的攻击类型,他利用的是使用未筛选的用户输入来形成数据库命令的应用程式。假如应用程式兴高采烈地使用用户键入表单域中的内容来创建 SQL 命令字符串,就会将您暴露在这一风险下:恶意用户只需访问该页并输入欺诈参数,就能够修改查询的性质。您能够在此处了解更多有关 SQL 注入的信息。

要阻止 SQL 注入攻击,有许多方法。以下介绍最常见的技巧。

确保用户输入属于适当的类型,并遵循预期的模式(邮政编码、身份证号,电子邮件等)。假如预期来自文本框的数字,请在用户输入无法转换为数字的内容时阻止该请求。

使用参数化的查询,使用存储过程更好。

使用 SQL Server 权限来限制各个用户能够对数据库执行的操作。例如,您可能需要禁用 xp_cmdshell 或将该操作的权限仅限于管理员。

假如使用存储过程,能够显著降低发生这种攻击的可能性。实际上,有了存储过程,您就无需动态地撰写 SQL 字符串。此外,SQL Server 中将验证任何参数是否具备指定的类型。虽然光是这些并不是百分百安全的技巧,但是加上验证的话,将足以提高安全性。

更为重要的是,应确保只有经过授权的用户才能够执行可能具备严重后果的操作,如删除表。这需要认真仔细地设计应用程式的中间层。好的技巧(不光是为了安全性)应把焦点集中在角色上。应当将用户分组为各种角色,并为各个角色定义一个包含一组最少的权限的帐户。

几周前,Wintellect Web 站点受到一种很复杂的 SQL 注入的攻击。那位黑客试图创建并启动一个 FTP 脚本来下载一个可能是恶意的可执行程式。幸运的是,这次攻击失败了。或,其实是强用户验证,使用存储过程和使用 SQL Server 权限,导致了攻击未能成功?

总而言之,您应当遵循这些指南,以避免被注入有害的 SQL 代码:

使用尽可能少的权限运行,永远不以“sa”身份执行代码。

将访问限制给内置的存储过程。

最好选择使用 SQL 参数化查询。

不通过字符串串连来生成语句,不回显数据库错误。

隐藏域

在传统的 ASP 中,隐藏域是唯一一种在请求之间保持数据的方法。您需要在下一个请求中检索的任何数据都被打包到隐藏的 域中,并执行回程。假如有人在客户端上修改了该域中存储的值,会怎样?只要文本是明文的,服务器端环境就无法测知这一情况。ASP.NET 中,页和各个控件的 ViewState 属性有两个用途。一方面,ViewState 是跨请求保持状态的方法;另一方面,ViewState 使您能够在受保护的、不易篡改的隐藏域中存储自定义值。

如图 2 所示,视图状态被附加了一个哈希值,对于每条请求,都会检查该值,以检测是否发生了篡改。除少数几种情况外,没有任何理由要在 ASP.NET 中使用隐藏域。视图状态能够以安全得多的方式实现相同的功能。前面开门见山地讲到过,在明文的隐藏域中存储敏感的值(如价格或信用卡周详信息),相当于对黑客张开大门;视图状态甚至能够使这种不好的做法比以前更为安全,因为视图状态具备数据保护机制。但是,请牢记,视图状态能够防止篡改,但是并不能确保保密性,除非使用加密 ? 存储在视图状态中的信用卡周详信息无论怎样都有风险。

在 ASP.NET 中,哪些情况下使用隐藏域是可接受的?当您生成需要将数据发送回服务器的自定义控件时。例如,假定您要创建一个支持重派列顺序的新 DataGrid 控件。您需要在回发中将新的顺序发送回服务器。假如不将这些信息存储到隐藏域中,又能够存储到哪里?

假如隐藏域为读/写域,即预期客户端会写入他,没什么办法能够完全制止黑客攻击。您能够尝试哈希或加密该文本,但这并不能让您合理地确信不会遭受黑客攻击。此时,最好的防御就是让隐藏域包含惰性和无害的信息。

此外,应当注意 ASP.NET 公开了一个鲜为人知的类,可用于编码和哈希任何序列化的对象.该类为 LosFormatterViewState 实现用于创建回程到客户端的编码文本正是同一个类。

private string EncodeText(string text) {
  StringWriter writer = new StringWriter();
  LosFormatter formatter = new LosFormatter();
  formatter.Serialize(writer, text);
  return writer.ToString();
}

前面的代码片段演示了怎样使用 LosFormatter 来创建类似视图状态的内容,对其编码并进行哈希。

电子邮件和垃圾邮件

在本文结尾,请让我指出,最常见的攻击中至少有两种(经典的 XSS 和一次单击)通常是通过诱使不抱怀疑的受害者单击诱惑性和欺骗性的链接来发起的。很多时候我们都能够在自己的收件箱中发现这样的链接,虽然有反垃圾邮件过滤器。几美元就能够买到大量电子邮件地址。用来生成这种列表的其中一种主要的技巧就是扫描 Web 站点上的公共页,查找并获取任何看上去像电子邮件的内容。

假如页上显示了电子邮件地址,很可能或早或晚这个地址都会被自动 Web 程式捕获。真的吗?当然,这要看该电子邮件是怎样显示的。假如硬编码他,您输定了。假如采用其他表示形式(如 dino-at-microsoft-dot-com),是否能够骗过自动 Web 程式不太清楚,但能让任何阅读您的页并想建立合法联系的人光火,倒是一定的。

总体说来,您应当确定一种方法,将电子邮件动态地生成为 mailto 链接。Marco Bellinaso 编写的一个免费组件恰好能够完成这项工作。您能够从 DotNet2TheMax Web 站点获得该组件的全部源代码。

小结

有人怀疑 Web 可能是任何运行时环境中敌意最盛的吗?根源在于谁都能够访问 Web 站点,并尝试向他传递好的或坏的数据。但是,创建不接受用户输入的 Web 应用程式,又有什么意义呢?

我们还是直面现实吧:无论您的防火墙怎样强大,无论您怎样频繁地应用可用的修补程式,只要您运行的 Web 应用程式先天包含缺陷,攻击者迟早都能够通过主通道,也就是端口 80,直接进入您的系统的最核心部分。

ASP.NET 应用程式和其他 Web 应用程式相较,既不更易受攻击,也不更安全。安全性和漏洞同样根植于编码实践、实际经验和团队合作。假如网络不安全,那么任何应用程式都不安全;类似地,无论网络怎样安全,管理怎样精良,假如应用程式存在缺陷,攻击者总是能够得手。

ASP.NET 的好处是提供了一些好的工具,只需少量工作,就能够将安全标准提升到能够接受的级别。当然,这并不是 足够高的级别。不应纯粹以来 ASP.NET 的内置解决方案,同样也不应忽视他们。尽可能多地了解常见的攻击。

本文提供了内置功能的带注释的列表,连同一些有关攻击和防御的背景知识。用来检测传出的攻击的技巧是另一回事,可能需要一篇专门的文章来进行介绍。

喜欢本文,那就收藏到:

    Del.icio.us Google书签 Digg Live Bookmark Technorati Furl Yahoo书签 Facebook 百度搜藏 新浪ViVi 365Key网摘 天极网摘 和讯网摘 博拉网 POCO网摘 添加到饭否 QQ书签 Digbuzz我挖网
相关评论  我也要评论
还没有关于此文章的相关评论!
  • 昵称: (为空则显示guest)
  • 评论分数: ★ ★ ★★★ ★★★★ ★★★★★
  • 评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
  • 导航
    赞助商
    文章类别
    订阅