New <%: %> Syntax for HTML Encoding Output in ASP.NET 4 (and ASP.NET MVC 2)
<%: %>这有助于保护您的应用程序和网站对注射跨站点脚本(XSS)和HTML注入攻击,并使您能够使用一个漂亮简洁的语法。
HTML Encoding
Cross-site script injection (XSS) and HTML encoding attacks are two of the most common security issues that plague web-sites and applications. They occur when hackers find a way to inject client-side script or HTML markup into web-pages that are then viewed by other visitors to a site. This can be used to both vandalize a site, as well as enable hackers to run client-script code that steals cookie data and/or exploits a user’s identity on a site to do bad things.
注入跨站点脚本(XSS)和HTML编码攻击是网站和应用程序中最常见的两种安全问题。他们发生在当黑客找到一种方法将客户端脚本或HTML标记成网页,然后被其他游客到网站。这可以用来摧残一个站点,以及使黑客窃取cookie数据运行客户端脚本代码和/或利用网站上的用户的身份去做坏事。
One way to help mitigate against cross-site scripting attacks is to make sure that rendered output is HTML encoded within a page. This helps ensures that any content that might have been input/modified by an end-user cannot be output back onto a page containing tags like <script> or <img> elements.
减轻跨站点脚本攻击的一种方法是确保呈现在页面输出HTML编码。这有助于确保任何内容,可能已经被一个终端用户输入/修改不能输出返回到页面包含标签像<script>或< img >元素。
How to HTML Encode Content Today
ASP.NET applications (especially those using ASP.NET MVC) often rely on using <%= %> code-nugget expressions to render output. Developers today often use the Server.HtmlEncode() or HttpUtility.Encode() helper methods within these expressions to HTML encode the output before it is rendered. This can be done using code like below:
ASP.NET应用(尤其是使用ASP.NET MVC)往往依赖于使用<%= % > code-nugget 表达式呈现输出。开发人员通常使用Server.HtmlEncode()或HttpUtility.Encode()辅助方法在这些表达式之前呈现HTML编码输出。可以使用下面的代码:
<div class="cssContent"> <%= Server.HtmlEncode(Model.Content) %> </div>
While this works fine, there are two downsides of it:
1. It is a little verbose
2. Developers often forget to call the Server.HtmlEncode method – and there is no easy way to verify its usage across an app
虽然这工作很好,但有两个缺点:
1. 它有点冗长
2. 开发人员常常忘记打电话给服务器。HtmlEncode方法,没有简单的方法来验证其在一个应用程序使用
New <%: %> Code Nugget Syntax
With ASP.NET 4 we are introducing a new code expression syntax (<%: %>) that renders output like <%= %> blocks do – but which also automatically HTML encodes it before doing so. This eliminates the need to explicitly HTML encode content like we did in the example above. Instead, you can just write the more concise code below to accomplish the exact same thing:
ASP.NET 4为我们引入一个新的代码表达式语法(<%: %>),使输出像<% = %>块一样——但也自动的HTML编码之前这样做。这消除了需要显式地HTML编码内容就像我们在上面的示例中所做的那样。相反,您可以编写以下更简洁的代码来完成同样的事:
<div class="cssContent"> <%: Server.HtmlEncode(Model.Content) %> </div>
We chose the <%: %> syntax so that it would be easy to quickly replace existing instances of <%= %> code blocks. It also enables you to easily search your code-base for <%= %> elements to find and verify any cases where you are not using HTML encoding within your application to ensure that you have the correct behavior.
我们选择了< %:% >语法,这样很容易迅速取代现有的实例<% = %>代码块。它还使您可以轻松地搜索代码库为<% = %>元素来查找和验证任何情况下,你不是在应用程序中使用HTML编码,以确保你有正确的行为。
Avoiding Double Encoding
While HTML encoding content is often a good best practice, there are times when the content you are outputting is meant to be HTML or is already encoded – in which case you don’t want to HTML encode it again.
虽然HTML编码内容通常是一个好的最佳实践,有些时候你输出的内容是HTML或已经编码——在这种情况下,你不想再HTML编码。
ASP.NET 4 introduces a new IHtmlString interface(along with a concrete implementation: HtmlString) that you can implement on types to indicate that its value is already properly encoded (or otherwise examined) for displaying as HTML, and that therefore the value should not be HTML-encoded again. The <%: %> code-nugget syntax checks for the presence of the IHtmlString interface and will not HTML encode the output of the code expression if its value implements this interface. This allows developers to avoid having to decide on a per-case basis whether to use <%= %> or <%: %> code-nuggets. Instead you can always use <%: %> code nuggets, and then have any properties or data-types that are already HTML encoded implement the IHtmlString interface.
ASP.NET 4介绍了一个新的IHtmlString接口(以及一个具体的实现:HtmlString),您可以实现类型来表明它的价值已经正确编码(或检查)显示为HTML,因此价值不应该再次HTML-encoded。<%: %>
code-nugget语法检查IHtmlString界面的存在,不会HTML编码的输出表达式如果其价值实现这个接口的代码。这允许开发人员避免per-case的基础上决定是否使用<%= %>和<%: %> code-nuggets。相反你总是可以使用<%: %>代码碎块,然后有任何属性或数据类型已经HTML编码实现IHtmlString接口。
Using ASP.NET MVC HTML Helper Methods with <%: %>
For a practical example of where this HTML encoding escape mechanism is useful, consider scenarios where you use HTML helper methods with ASP.NET MVC. These helper methods typically return HTML. For example: the Html.TextBox() helper method returns markup like <input type=”text”/>. With ASP.NET MVC 2 these helper methods now by default return HtmlString types – which indicates that the returned string content is safe for rendering and should not be encoded by <%: %> nuggets.
对于一个实际的例子,这个HTML编码逃避机制是非常有用的,考虑场景使用HTML辅助方法与ASP.NET MVC。这些辅助方法通常返回的HTML。例如:Html.TextBox()辅助方法返回标记就像<input type=”text”/>。ASP.NET MVC 2现在这些辅助方法默认情况下返回HtmlString类型——这表明,返回的字符串内容是安全的渲染,不应由<%: %>编码掘金。
This allows you to use these methods within both <%= %> code nugget blocks:
As well as within <%: %> code nugget blocks:
In both cases above the HTML content returned from the helper method will be rendered to the client as HTML – and the <%: %> code nugget will avoid double-encoding it.
This enables you to default to always using <%: %> code nuggets instead of <%= %> code blocks within your applications. If you want to be really hardcore you can even create a build rule that searches your application looking for <%= %> usages and flags any cases it finds as an error to enforce that HTML encoding always takes place.
Scaffolding ASP.NET MVC 2 Views
When you use VS 2010 (or the free Visual Web Developer 2010 Express) to build ASP.NET MVC 2 applications, you’ll find that the views that are scaffolded using the “Add View” dialog now by default always use <%: %> blocks when outputting any content. For example, below I’ve scaffolded a simple “Edit” view for an Article object. Note the three usages of <%: %> code nuggets for the label, textbox, and validation message (all output with HTML helper methods):
Summary
The new <%: %> syntax provides a concise way to automatically HTML encode content and then render it as output. It allows you to make your code a little less verbose, and to easily check/verify that you are always HTML encoding content throughout your site. This can help protect your applications against cross-site script injection (XSS) and HTML injection attacks.