每当用户在我的web应用程序中的页面中发布包含<或>的内容时,我都会引发此异常。

我不想因为有人在文本框中输入了字符而引发异常或使整个web应用程序崩溃,但我正在寻找一种优雅的方式来处理这一问题。

捕获异常并显示

出现错误,请返回并重新键入整个表单,但这次请不要使用<

我觉得不够专业。

禁用后验证(validateRequest=“false”)肯定可以避免此错误,但这会使页面容易受到许多攻击。

理想情况下:当发生包含HTML限制字符的回发时,表单集合中的回发值将自动进行HTML编码。因此,我的文本框的.Text属性将是&lt;html&gt;

有没有办法让我从处理者那里做到这一点?


当前回答

如果不想禁用ValidateRequest,则需要实现JavaScript函数以避免异常。这不是最好的选择,但它有效。

function AlphanumericValidation(evt)
{
    var charCode = (evt.charCode) ? evt.charCode : ((evt.keyCode) ? evt.keyCode :
        ((evt.which) ? evt.which : 0));

    // User type Enter key
    if (charCode == 13)
    {
        // Do something, set controls focus or do anything
        return false;
    }

    // User can not type non alphanumeric characters
    if ( (charCode <  48)                     ||
         (charCode > 122)                     ||
         ((charCode > 57) && (charCode < 65)) ||
         ((charCode > 90) && (charCode < 97))
       )
    {
        // Show a message or do something
        return false;
    }
}

然后在后面的代码中,在PageLoad事件中,使用下一个代码将属性添加到控件中:

Me.TextBox1.Attributes.Add("OnKeyPress", "return AlphanumericValidation(event);")

其他回答

您还可以使用JavaScript的转义(字符串)函数来替换特殊字符。然后服务器端使用server.URLDecode(字符串)将其切换回来。

这样,您就不必关闭输入验证,其他程序员将更清楚地知道字符串可能包含HTML内容。

这些建议对我都不起作用。无论如何,我不想关闭整个网站的这个功能,因为99%的时间我不希望我的用户在web表单上放置HTML。我刚刚创建了自己的变通方法,因为我是唯一一个使用这个特定应用程序的人。我在后面的代码中将输入转换为HTML并将其插入数据库。

我认为你试图对所有发布的数据进行编码,这是从错误的角度来攻击它。

注意,“<”也可以来自其他外部源,如数据库字段、配置、文件、提要等。

此外,“<”本身并不危险。这只在特定的上下文中是危险的:当编写尚未编码为HTML输出的字符串时(因为XSS)。

在其他上下文中,不同的子字符串是危险的,例如,如果将用户提供的URL写入链接,则子字符串“javascript:”可能是危险的。另一方面,在SQL查询中插入字符串时,单引号字符是危险的,但如果它是从表单提交的名称的一部分或从数据库字段读取的名称,则完全安全。

底线是:你不能过滤危险字符的随机输入,因为任何字符在正确的情况下都可能是危险的。您应该在某些特定字符可能会变得危险的地方进行编码,因为它们交叉到具有特殊含义的不同子语言中。将字符串写入HTML时,应使用Server.HtmlEncode对HTML中具有特殊含义的字符进行编码。如果将字符串传递给动态SQL语句,则应编码不同的字符(或者更好,让框架使用准备好的语句等为您进行编码)。。

当您确定在传递字符串到HTML的任何地方都进行HTML编码时,请在<%@Page…%>中设置ValidateRequest=“false”.aspx文件中的指令。

在.NET4中,您可能需要做更多的工作。有时还需要将<httpRuntime requestValidationMode=“2.0”/>添加到web.config(参考)。

我知道这个问题是关于表单发布的,但我想为在其他情况下收到此错误的人添加一些详细信息。它也可能发生在用于实现web服务的处理程序上。

假设您的web客户端使用ajax发送POST或PUT请求,并向web服务发送json或xml文本或原始数据(文件内容)。因为web服务不需要从Content-Type头中获取任何信息,所以JavaScript代码没有将此头设置为ajax请求。但如果您没有在POST/PUT ajax请求上设置此标头,Safari可能会添加此标头:“Content-Type:application/x-www-form-urlencoded”。我在iPhone上的Safari 6上观察到了这一点,但其他Safari版本/OS或Chrome可能也会这样做。因此,当接收到此Content-Type标头时,.NETFramework的某些部分假定请求体数据结构对应于html表单发布,而不是html表单发布,并引发HttpRequestValidationException异常。显然,要做的第一件事是在POST/PUT ajax请求中始终将Content-Type头设置为表单MIME类型以外的任何类型,即使它对web服务没有用处。

我还发现了这个细节:在这些情况下,当代码尝试访问HttpRequest.Params集合时,HttpRequestValidationException异常会出现。但令人惊讶的是,当它访问HttpRequest.ServerVariables集合时,这个异常并没有出现。这表明,虽然这两个集合看起来几乎相同,但一个通过安全检查访问请求数据,另一个则没有。

您应该使用Server.HtmlEncode方法来保护您的站点免受危险输入。

此处有更多信息