领先技术: 子类化和重写ASP.NET页面 - 第II部分2011-12-31 MSDN Dino Esposito最近一个很偶然的机会,我发现了一个大型网站,上面全是一些极其简单的 Web 用户控件,确切地说是一些 ASCX 文件。开发人员在发现所使用的服务器控件会出现异常行为后,往往认为这种方法是很有必要的。因此,开发人员将站点内的这类服务器控件全部更换为包含原始控件修改版本的用户控件(同时由于无法确定更换服务器控件会导致何种后果,因此开发人员还替换了其他大量控件。)开发人员认为,将这样一种额外的抽象层置于页面和控件之间会更可靠。另外一个好处就是可以在 ASP.NET 应用程序中轻松替换用户控件(如果需要的话),而无需修改二进制文件和重新启动应用程序。(这种情况并非始终都会发生,但有些部署方案会要求执行该操作。)曾经有公司请我来审阅应用程序,他们问我的第一个问题就是:“是否有更好的方法可以在不大量返工每个页面的情况下替换整个站点的服务器控件?”我在自己主持的 2007 年 4 月专栏中,针对如何在不修改原始源代码的情况下对 ASP.NET 网站进行有限的(有时是临时的)修改给出了几种解决方案。本月我又发现几种技巧,无需修改源代码,通过声明的方式即可替换服务器控件和 URL。当时我无法立即回答他们的问题,但却知道如何找到解决方法。我想如果是我开发了 ASP.NET 基础结构,我会在配置文件中放置某种设置,以便开发人员能够通过声明的方式将标记映射到控件。在 ASP.NET 中这并非是一个全新的理念。早在 ASP.NET 1.x 中,您就可以通过声明的方式更改一些与代码相关的内容,例如网页和用户控件的基类。(但是,这种方法只适用于未在 Page 指令中显式使用 Inherits 子句的页面和用户控件。)因此我产生了一个疑问,为什么服务器控件不可以采取这种方法呢。事实证明我当时的推断是正确的:ASP.NET 2.0 正是为此才提供了 <tagMapping> 节。背景知识我想还是先向大家介绍一些背景知识。此方案始于一次内部安全审查,当时客户发现应用程序内存在一个可能导致经典 SQL 注入式攻击的漏洞。公司对这一漏洞应用了快速修补程序,但却导致了另一个问题。在客户的网站上,许多页面都允许查询字符串中包含固定的五字符代码。这种代码会随后用于构成 SQL 语句。该公司当时仍在运行类似以下内容的代码:
Dim code As String = Request.QueryString(“Code”).ToString();Dim command As String = _  “SELECT * FROM customers WHERE id=’” & code & “’”
说心里话,我真的希望您的网站已经不再运行类似代码!这种代码完全盲目地信任任何通过查询字符串传递的信息,并会将该信息附加到构成 SQL 命令的字符串。这样做会形成非常严重的安全隐患。手段高明的黑客能够轻而易举地发现那些看似正常、实则危险的文本,它们能够将原始的和为特定目的编写的 SQL 命令变成危险的攻击。如果您需要更多有关 SQL 注入的详细信息,建议您先阅读 Paul Litwin 撰写的文章“Stop SQL Injection Attacks Before They Stop You”。