今天介绍ASP.NET 4引入的新的语法特性——即在代码块中自动产生HTML编码输出的能力。这可以帮助保护应用程序和站点免受跨站点脚本(XSS)注入和HTML注入攻击,并使你能够使用简洁的语法来做到这一点。

HTML编码

跨站点脚本注入(XSS)和HTML编码攻击是两个最常见的折磨网站和应用程序的安全性问题。当黑客发现了一个可以把客户端脚本或HTML标记注入到页面的方法,随后其他访问者查看此页面时就会发生此类问题。这可能会被用于破坏网站,还可以让黑客能够运行客户端脚本代码盗取cookie数据并利用用户的身份在网站上做坏事。

一种避免跨站点脚本攻击的方法是确保呈现的输出在页面中都是 HTML 编码的。这就确保了任何被终端用户输入/修改的内容在输出回页面时都不会包含像<script>或<img>元素的标签。

过去如何对内容进行HTML编码

ASP.NET 应用程序(尤其是使用ASP.NET MVC)经常依赖于使用<%= %>代码块表达式来呈现输出。开发人员经常要在表达式中使用 Server.HtmlEncode() 或 HttpUtility.Encode() 辅助方法来对输出内容在呈现前进行 HTML 编码。例如像下面的代码:

VS2010与.NET4系列 19.ASP.NET4中新的HTML编码的<%: %>语法_ HTML Encoding Outpu

尽管这样工作良好,但有两个不好的地方:

  1. 有些啰嗦
  2. 开发人员经常忘记调用 Server.HtmlEncode() 方法,还没有容易的检验它是否使用的方法

新的 <%: %>代码块语法

使用ASP.NET 4引入的新的代码表达式语法(<%: %>),可以呈现像 <%= %> 块的输出,但在输出前自动进行了 HTML 编码。这样就消除了像上面那样需要显式进行HTML编码内容的步骤。现在只要编写下面这样更简洁的代码来完成相同的任务了:

VS2010与.NET4系列 19.ASP.NET4中新的HTML编码的<%: %>语法_ Code Nuggets_02

避免双重编码

尽管 HTML 编码内容是一个良好的最佳实践,但有时候输出的内容可能已经被编码过了——这时你不想再对其再次进行编码。

ASP.NET 4 引入了新的 IHtmlString 接口(和具体实现:HtmlString),它让你能够实现一种类型来表示它的值已经被恰当地编码了(或已经检查过了),可以作为 HTML 显示了,因此值不应当再次被 HTML 编码。<%: %>代码块语法会检测到 IHtmlString 的存在,如果值实现了这个接口就不会对代码表达式的输出进行 HTML 编码。这就避免了让开发人员选择使用 <%= %> 还是 <%: %>代码块。你可以始终使用 <%: %>代码块,并使用任何实现 IHtmlString 接口已经对值进行HTML编码的任何属性或数据类型。

对 <%: %> 使用 ASP.NET MVC 的 HTML 辅助方法

考虑下在ASP.NET MVC中使用 HTML 辅助方法的场景。这些辅助方法通常会返回 HTML。例如:Html.TextBox() 辅助方法返回像 <input type="text"/> 的标记。使用 ASP.NET MVC 2 这些辅助方法默认都返回 HtmlString 类型,这表示返回的字符串内容对呈现是安全的不应当再被 <%: %>块编码了。

可以在 <%= %> 代码块中使用这些方法:

VS2010与.NET4系列 19.ASP.NET4中新的HTML编码的<%: %>语法_ <%:%>_03

也可以在 <%: %> 代码块中使用:

VS2010与.NET4系列 19.ASP.NET4中新的HTML编码的<%: %>语法_ASP.NET 4_04

上面两种情况中,从辅助方法返回的内容都将作为 HTML 呈现到客户端,<%: %>代码块会避免双重编码。

支架支撑ASP.NET MVC2 视图

使用VS2010(或VWD2010 Express)构建 ASP.NET MVC 2 应用程序时,你会发现使用"Add Viw" 对话框支撑的视图现存默认都是使用 <%: %>块来输出任何内容了。例如,下面我们为 Article 对象搭建(scaffold)了一个简单的“编辑”视图。注意对标签、文本框和验证消息使用的 <%: %>代码块:

VS2010与.NET4系列 19.ASP.NET4中新的HTML编码的<%: %>语法_ <%:%>_05

总结

新的 <%: %> 语法提供了自动化HTML 编码内容随后作为输出呈现的的简洁方法。它允许你让你的代码不那么啰嗦,让你的站点使用进行了 HTML 编码内容。这可以帮助保护你的应用程序防止跨站点注入(XSS)和HMTL注入攻击。