每当用户在我的web应用程序中的页面中发布包含<或>的内容时,我都会引发此异常。
我不想因为有人在文本框中输入了字符而引发异常或使整个web应用程序崩溃,但我正在寻找一种优雅的方式来处理这一问题。
捕获异常并显示
出现错误,请返回并重新键入整个表单,但这次请不要使用<
我觉得不够专业。
禁用后验证(validateRequest=“false”)肯定可以避免此错误,但这会使页面容易受到许多攻击。
理想情况下:当发生包含HTML限制字符的回发时,表单集合中的回发值将自动进行HTML编码。因此,我的文本框的.Text属性将是<;html>;
有没有办法让我从处理者那里做到这一点?
我找到了一个使用JavaScript编码数据的解决方案,数据在.NET中解码(不需要jQuery)。
使文本框成为HTML元素(如文本区域)而不是ASP元素。添加隐藏字段。将以下JavaScript函数添加到标头中。函数boo(){targetText=document.getElementById(“HiddenField1”);sourceText=document.getElementById(“userbox”);targetText.value=转义(sourceText.innerText);}
在文本区域中,包含一个调用boo()的onchange:
<textarea id="userbox" onchange="boo();"></textarea>
最后,在.NET中,使用
string val = Server.UrlDecode(HiddenField1.Value);
我知道这是单向的-如果你需要双向的,你必须要有创造性,但如果你不能编辑web.config,这就提供了一个解决方案
下面是我(MC9000)通过jQuery创建并使用的示例:
$(document).ready(function () {
$("#txtHTML").change(function () {
var currentText = $("#txtHTML").text();
currentText = escape(currentText); // Escapes the HTML including quotations, etc
$("#hidHTML").val(currentText); // Set the hidden field
});
// Intercept the postback
$("#btnMyPostbackButton").click(function () {
$("#txtHTML").val(""); // Clear the textarea before POSTing
// If you don't clear it, it will give you
// the error due to the HTML in the textarea.
return true; // Post back
});
});
以及标记:
<asp:HiddenField ID="hidHTML" runat="server" />
<textarea id="txtHTML"></textarea>
<asp:Button ID="btnMyPostbackButton" runat="server" Text="Post Form" />
这很有效。如果黑客试图绕过JavaScript发帖,他们只会看到错误。您还可以将所有这些编码的数据保存在数据库中,然后(在服务器端)对其进行解析,并在其他地方显示之前分析和检查攻击。
解决方案
我不想关闭后验证(validateRequest=“false”)。另一方面,应用程序崩溃是不可接受的,因为一个无辜的用户碰巧键入了<x或其他内容。
因此,我编写了一个客户端javascript函数(xssCheckValidates),用于进行初步检查。当试图发布表单数据时,调用此函数,如下所示:
<form id="form1" runat="server" onsubmit="return xssCheckValidates();">
该功能非常简单,可以改进,但它正在发挥作用。
请注意,这样做的目的不是为了保护系统免受黑客攻击,而是为了保护用户免受不良体验。在服务器上完成的请求验证仍处于打开状态,这是系统保护的一部分(在一定程度上它能够做到这一点)。
我之所以在这里说“部分”,是因为我听说内置的请求验证可能还不够,所以可能需要其他补充手段来提供充分的保护。但是,我这里介绍的javascript函数与保护系统无关。这只是为了确保用户不会有糟糕的体验。
你可以在这里试试:
函数xssCheckValidates(){var有效=真;var inp=document.querySelectorAll(“输入:not(:禁用):not([readonly]):not([type=hidden])”+“,textarea:not(:禁用):not([readonly])”);对于(变量i=0;i<inp.length;i++){if(!inp[i].readOnly){如果(inp[i].value.indexOf('<')>-1){有效=假;打破}如果(inp[i].value.indexOf('&#')>-1){有效=假;打破}}}if(有效){返回true;}其他{alert('在一个或多个文本字段中,您键入了\r\n字符“<”或字符序列“&#”。\r\n\r\n遗憾的是,这是不允许的,因为它可用于黑客尝试。\r\n\r\n请编辑字段并重试。');return false;}}<form onsubmit=“return xssCheckValidates();”>尝试键入<或&#<br/><input-type=“text”/><br/><textarea></textarea><input-type=“submit”value=“Send”/></form>
最后但同样重要的是,请注意ASP.NET数据绑定控件在数据绑定期间自动编码值。这将更改ItemTemplate中包含的所有ASP.NET控件(TextBox、Label等)的默认行为。以下示例演示了(ValidateRequest设置为false):
aspx
<%@ Page Language="C#" ValidateRequest="false" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication17._Default" %> <html> <body>
<form runat="server">
<asp:FormView ID="FormView1" runat="server" ItemType="WebApplication17.S" SelectMethod="FormView1_GetItem">
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
<asp:Label ID="Label1" runat="server" Text="<%#: Item.Text %>"></asp:Label>
<asp:TextBox ID="TextBox2" runat="server" Text="<%#: Item.Text %>"></asp:TextBox>
</ItemTemplate>
</asp:FormView>
</form>
代码隐藏
public partial class _Default : Page
{
S s = new S();
protected void Button1_Click(object sender, EventArgs e)
{
s.Text = ((TextBox)FormView1.FindControl("TextBox1")).Text;
FormView1.DataBind();
}
public S FormView1_GetItem(int? id)
{
return s;
}
}
public class S
{
public string Text { get; set; }
}
案例提交值:';
标签1.文本值:';
TextBox2.文本值:&#39;
案例提交值:<script>alert('attack!')</脚本>
标签1.文本值:<script>alert('attack!')</脚本>
TextBox2.文本值:<;脚本>;警报(';攻击!';)</脚本>;