在遗留的ASP.NET 4.0应用程序中,我们正在更新各种安全问题,我们遇到包含HtmlEncoded项目的列表框和下拉列表的问题。对于包含撇号的ListItem文本值,浏览器无法识别列表框和下拉列表中的编码,因此在呈现时无法将文本解码回撇号。
对于请求的示例:
考虑Test.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Test.aspx.cs" Inherits="Test" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<form id="form1" runat="server">
<div>
<asp:ListBox runat="server" ID="TheListBox" ></asp:ListBox>
</div>
</form>
</body>
</html>
它的代码隐藏:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
TheListBox.Items.Add(new ListItem("'hello'", HttpUtility.HtmlEncode("hi")));
TheListBox.Items.Add(new ListItem(HttpUtility.HtmlEncode("David's Test"), "hi"));
}
}
结果页面如下所示:
在发布的问题here非常相似的问题中,OP选择了一个答案,仅仅承认Microsoft在发布ASP.NET 4.0时将撇号的编码记录为更改。但是,对于我们来说,这个答案并没有解决浏览器端的渲染问题,我们已经在IE11和FireFox中看到了这个问题。也就是说,我们对编码本身没有任何问题,但事实上编码没有得到一致的尊重。
对我们来说进一步的问题是我们的应用程序的某些方面将列表框之间的编码数据移动以便在回发时提交,然后非解码撇号的存在会导致ASP.NET反XSS检查在请求上抛出异常,思考当它不是时,价值是恶意的。如果删除编码,则回发成功。
该站点已设置为在web.config中呈现具有.Net 3.5兼容性的控件。我们已经尝试完全删除它,然后显式设置为4.0(可能是默认设置),这两者都没有任何区别。我已经考虑过滚动我自己的HtmlEncode覆盖来忽略包含撇号的字符串,但对于大多数浏览器按预期在非列表框实体上呈现编码标记的实例(例如文本框和标签),这似乎是严苛的。
是否有一些其他简单/明显的解决方法或设置我只是忽略了解决这个问题?我搜索了SO和其他一般间接讨论撇号问题的网站,但似乎都没有一个特定于ASP.NET 4.0的一致解决方案。
虽然我意识到这个问题没有得到太多响应,但我将在这里提出一些额外的发现,这几乎构成了一个答案,可以帮助其他任何人维护遗留的ASP.NET 4.0站点。
原始帖子中说明的真正问题是ListBox中的项目是双重编码的。这源于源中所示的初始显式HtmlEncoding,以及显然在渲染时调用的附加HtmlEncode。
我们认为,问题在于,许多(但显然不是全部)库存ASP.NET 4.x系列控件在渲染时会自动调用HtmlEncode。
我们注意到,当一个简单的ListBox控件包含一个带有&符号的项目的页面的渲染内容包含在一个显式的HtmlEncode调用中时,我们做了这个推断实际上是用一个很难的'&'来呈现,暗示它已经是HtmlEncoded。
ASP TextBox,DropDownList和ListBox控件似乎在渲染时对其内容进行HtmlEncode。 ASP Label控件没有。 GridView控件具有显式启用/禁用HtmlEncoding的属性。这些控件的Html等价物,例如使用runat =“server”属性修改的常规HTML元素,在渲染时也是HtmlEncoded。
最重要的是,除了上面列出的那些之外,任何关于给定控件HtmlEncodes其易受攻击内容的问题只能通过测试相关控件来完全知道。
当我发现有关确定哪些控件提供自己的编码的更多信息时,我将更新此信息。
编辑:
附加测试显示以下两个控件都是HtmlEncoded,当值在标记中显式设置或者以progrmmatically方式添加/定义时:
我强烈怀疑,但尚未测试,任何使用runat ='server'的原生HTML控件都会表现得相似。