当前位置:  开发笔记 > 后端 > 正文

从客户端检测到潜在危险的Request.Form值

如何解决《从客户端检测到潜在危险的Request.Form值》经验,为你挑选了26个好方法。

每当用户在我的Web应用程序中发布包含<>在页面中的内容时,我都会抛出此异常.

我不想进入关于抛出异常或崩溃整个Web应用程序的聪明性的讨论,因为有人在文本框中输入了一个字符,但我正在寻找一种优雅的方法来处理这个问题.

捕获异常并显示

发生错误请返回并重新输入整个表单,但这次请不要使用<

对我来说似乎不够专业.

禁用post validation(validateRequest="false")肯定会避免此错误,但它会使页面容易受到许多攻击.

理想情况:当发回包含HTML限制字符的回发时,Form集合中的已发布值将自动进行HTML编码.所以.Text我的文本框的属性将是something & lt; html & gt;

有没有办法可以从处理程序中执行此操作?



1> JacquesB..:

我认为你是通过尝试编码所有发布的数据从错误的角度攻击它.

请注意," <"也可能来自其他外部源,如数据库字段,配置,文件,订阅源等.

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

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

底线是:您无法过滤危险字符的随机输入,因为在适当的情况下任何字符都可能是危险的.您应该在某些特定字符可能变得危险的位置进行编码,因为它们会跨越到具有特殊含义的不同子语言.将字符串写入HTML时,应使用Server.HtmlEncode对HTML中具有特殊含义的字符进行编码.如果将字符串传递给动态SQL语句,则应编码不同的字符(或者更好,让框架通过使用预处理语句等为您完成).

如果您确定在任何地方进行HTML编码,则将字符串传递给HTML,然后在文件validateRequest="false"中的<%@ Page ... %>指令中进行设置.aspx.

在.NET 4中,您可能需要做更多的事情.有时也需要添加到web.config(引用).


在MVC3中,这是model属性上的`[AllowHtml]`.
对于那些迟到的人:validateRequest ="false"进入Page指令(.aspx文件的第一行)
提示:在位置标记中放置``,以避免从网站的其余部分中删除验证提供的有用保护.
@MGOwen你也可以通过``中的``将page指令添加到web.config中.这样做会将属性应用于所有页面.
要为MVC 3全局禁用它,还需要`GlobalFilters.Filters.Add(new ValidateInputAttribute(false));```Application_Start()`.
[这个答案](http://stackoverflow.com/a/4269513/3429)到[这个问题](http://stackoverflow.com/questions/2673850/validaterequest-false-doesnt-work-in-asp-net -4)引用为您网站上的单个页面设置requestValidationMode ="2.0",这肯定比为整个网站关闭验证更安全.
在ASP.NET MVC中,Razor自2010年以来就自动使用HTML编码的字符串.所以我认为可以在一个人的POST控制器操作(接收表单数据)上安全地使用`[ValidateInput(false)]`

2> Zack Peterso..:

如果您使用的是ASP.NET MVC,则会出现此错误的不同解决方案:

ASP.NET MVC - 页面validateRequest = false不起作用?

为什么ValidateInput(False)不起作用?

ASP.NET MVC RC1,VALIDATEINPUT,可能的危险请求和PITFALL

C#样本:

[HttpPost, ValidateInput(false)]
public ActionResult Edit(FormCollection collection)
{
    // ...
}

Visual Basic示例:

 _
Function Edit(ByVal collection As FormCollection) As ActionResult
    ...
End Function


您还可以在类级别添加[ValidateInput(false)]属性.如果将其添加到基本控制器类,它将应用于所有控制器方法操作.

3> Anthony John..:

在ASP.NET MVC(从版本3开始)中,您可以将AllowHtml属性添加到模型的属性中.

它允许请求在模型绑定期间通过跳过属性的请求验证来包含HTML标记.

[AllowHtml]
public string Description { get; set; }


唯一正确的答案!禁用控制器操作的验证是hacky.要在应用程序级别禁用验证,必须挂起开发人员!
声明性地比在控制器中做得更好!
美丽!这就是_should_完成的方式.

4> JordanC..:

如果您使用的是.NET 4.0,请确保将其添加到标记内的web.config文件中:



在.NET 2.0中,请求验证仅应用于aspx请求.在.NET 4.0中,这扩展到包括所有请求.您可以通过指定以下内容恢复为在处理时执行XSS验证.aspx:

requestValidationMode="2.0"

您可以通过指定完全禁用请求验证:

validateRequest="false"


在``标签内.
看起来仅在机器上安装2.0框架时才有效.如果没有安装2.0框架但只安装了4.0框架怎么办?
我把它放在web.config中,但仍然是错误"有潜在危险的Request.Form值"

5> Carter Medli..:

对于ASP.NET 4.0,您可以通过将标记全部放在元素中来允许标记作为特定页面的输入而不是整个站点.这将确保您的所有其他页面都是安全的.您不需要放入ValidateRequest="false".aspx页面.


...
  
    
      
      
    
  
...

在web.config中控制它更安全,因为您可以在站点级别看到哪些页面允许标记作为输入.

您仍然需要以编程方式验证禁用请求验证的页面上的输入.



6> gligoran..:

之前的答案很棒,但没有人说过如何排除单个字段的HTML/JavaScript注入验证.我不知道以前的版本,但在MVC3 Beta中你可以这样做:

[HttpPost, ValidateInput(true, Exclude = "YourFieldName")]
public virtual ActionResult Edit(int id, FormCollection collection)
{
    ...
}

这仍然验证除被排除的字段之外的所有字段.关于这一点的好处是你的验证属性仍然验证字段,但你只是没有得到"从客户端检测到一个潜在危险的Request.Form值"异常.

我用它来验证正则表达式.我已经创建了自己的ValidationAttribute来查看正则表达式是否有效.由于正则表达式可以包含类似于我应用上述代码的脚本的东西 - 正则表达式仍在被检查是否有效,但如果它包含脚本或HTML则不然.


可悲的是,它似乎从MVC 3 RTW中删除了排除功能:(
在模型的属性上使用`[AllowHtml]`而不是Action上的`[ValidateInput]`来实现相同的最终结果.
它也不包含在MVC 4中
@Christof请注意,我的回答是5岁.我很久没有遇到过这个问题了,所以可能有更好的方法来处理它.关于这两个选项我认为这取决于你的情况.也许您在多个动作中公开该模型,在某些地方允许HTML或不允许HTML.在这种情况下```[AllowHtml]```不是一个选项.我建议查看这篇文章:http://weblogs.asp.net/imranbaloch/understanding-request-validation-in-asp-net-mvc-3,但它也有些陈旧,可能已经过时了.

7> ranthonissen..:

在ASP.NET MVC中,您需要在web.config中设置requestValidationMode ="2.0"和validateRequest ="false",并将ValidateInput属性应用于您的控制器操作:




    
        
    

[Post, ValidateInput(false)]
public ActionResult Edit(string message) {
    ...
}


对我来说,`validateRequest ="false"`不是必需的,只有`requestValidationMode ="2.0"`

8> Pavel Chuchu..:

您可以HTML编码文本框内容,但不幸的是,这不会阻止异常发生.根据我的经验,没有办法,你必须禁用页面验证.通过这样做,你说:"我会小心,我保证."



9> A.Dara..:

对于MVC,通过添加忽略输入验证

[ValidateInput(假)]

在控制器中的每个动作之上.



10> BenMaddox..:

您可以在Global.asax中捕获该错误.我仍然想验证,但显示适当的消息.在下面列出的博客上,可以获得这样的示例.

    void Application_Error(object sender, EventArgs e)
    {
        Exception ex = Server.GetLastError();

        if (ex is HttpRequestValidationException)
        {
            Response.Clear();
            Response.StatusCode = 200;
            Response.Write(@"[html]");
            Response.End();
        }
    }

重定向到另一个页面似乎也是对异常的合理响应.

http://www.romsteady.net/blog/2007/06/how-to-catch-httprequestvalidationexcep.html



11> 小智..:

这个问题的答案很简单:

var varname = Request.Unvalidated["parameter_name"];

这将禁用特定请求的验证.


我希望我能这样做.我正在使用.NET 4.5,这正是我需要的,因为我没有使用MVC,我无法更改web.config.

12> 小智..:

请记住,某些.NET控件会自动对输出进行HTML编码.例如,在TextBox控件上设置.Text属性将自动对其进行编码.这特别意味着转换<<,>进入>&进入&.所以要小心这样做......

myTextBox.Text = Server.HtmlEncode(myStringFromDatabase); // Pseudo code

但是,HyperLink,Literal和Label的.Text属性不会对HTML进行编码,因此包装Server.HtmlEncode(); 如果您想阻止输出到您的页面并随后执行,那么必须在这些属性上设置任何内容.

做一些实验,看看什么编码,什么不编码.



13> Mahdi jokar..:

在web.config文件中,在标记内插入带有属性requestValidationMode ="2.0"的httpRuntime元素.还要在pages元素中添加validateRequest ="false"属性.

例:


  
   
  
  
  


"pages"部分必须在"system.web"部分中.

14> 小智..:

如果您不想禁用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);")


@ Radu094:这个解决方案允许你保持ValidateRequest = true,这意味着黑客仍然会碰到那堵墙.投票UP,因为这使您比关闭ValidateRequest更不容易受到攻击.
这仍然会使应用程序容易受到伪造的POST请求的影响.普通用户在输入诸如:或引号等字符时会遇到问题,但普通黑客在将错误数据发布到服务器时没有问题.我会把这个waaay告诉我.

15> Piercy..:

似乎没有人提到下面的内容,但它解决了我的问题.在任何人说是的之前它是Visual Basic ...哎呀.

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Example.aspx.vb" Inherits="Example.Example" **ValidateRequest="false"** %>

我不知道是否有任何缺点,但对我来说这真的很棒.



16> Sel..:

另一种解决方案是

protected void Application_Start()
{
    ...
    RequestValidator.Current = new MyRequestValidator();
}

public class MyRequestValidator: RequestValidator
{
    protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
    {
        bool result = base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);

        if (!result)
        {
            // Write your validation here
            if (requestValidationSource == RequestValidationSource.Form ||
                requestValidationSource == RequestValidationSource.QueryString)

                return true; // Suppress error message
        }
        return result;
    }
}



17> Durgesh Pand..:

如果您使用的是框架4.0,那么web.config中的条目()


    
        
    

如果您使用的是框架4.5,那么web.config中的条目(requestValidationMode ="2.0")


    
    

如果你只想要单页,那么在你的aspx文件中你应该把第一行作为:

<%@ Page EnableEventValidation="false" %>

如果您已经有类似<%@ Page的内容,那么只需添加其余的=> EnableEventValidation="false"%>

我建议不要这样做.



18> blowdart..:

我想你可以在模块中做到这一点; 但这留下了一些问题; 如果要将输入保存到数据库怎么办?突然之间,因为你将编码数据保存到数据库,你最终信任它的输入,这可能是一个坏主意.理想情况下,您每次都会将原始未编码数据存储在数据库中并进行编码.

在每页级别禁用保护,然后每次编码是一个更好的选择.

您应该从Microsoft ACE团队查看更新,更完整的Anti-XSS库,而不是使用Server.HtmlEncode .



19> Jaider..:

在ASP.NET中,您可以捕获异常并对其执行某些操作,例如显示友好消息或重定向到另一个页面...还有可能您可以自己处理验证...

显示友好消息:

protected override void OnError(EventArgs e)
{
    base.OnError(e);
    var ex = Server.GetLastError().GetBaseException();
    if (ex is System.Web.HttpRequestValidationException)
    {
        Response.Clear();
        Response.Write("Invalid characters."); //  Response.Write(HttpUtility.HtmlEncode(ex.Message));
        Response.StatusCode = 200;
        Response.End();
    }
}



20> 小智..:

原因

默认情况下,ASP.NET会验证可能导致跨站点脚本(XSS)和SQL注入的潜在不安全内容的所有输入控件.因此,通过抛出上述异常,它不允许这样的内容.默认情况下,建议允许在每次回发时进行此检查.

在许多情况下,您需要通过Rich TextBoxes或Rich Text Editors向页面提交HTML内容.在这种情况下,您可以通过将@Page指令中的ValidateRequest标记设置为false 来避免此异常.

<%@ Page Language="C#" AutoEventWireup="true" ValidateRequest = "false" %>

这将禁用对已将ValidateRequest标志设置为false的页面的请求的验证.如果要禁用此功能,请检查整个Web应用程序; 您需要在web.config 部分将其设置为false


对于.NET 4.0或更高版本的框架,您还需要在部分中添加以下行以完成上述工作.


而已.我希望这可以帮助你摆脱上述问题.

引用者:ASP.Net错误:从客户端检测到一个潜在危险的Request.Form值



21> magritte..:

这里的其他解决方案都很不错,但是后面必须将[AllowHtml]应用于每个Model属性,这是一个很大的痛苦,特别是如果你在一个体面的网站上有超过100个模型.

如果像我一样,你想在网站范围内转换这个(恕我直言相当毫无意义)功能,你可以覆盖基本控制器中的Execute()方法(如果你还没有基本控制器我建议你做一个,它们可以是应用常用功能非常有用).

    protected override void Execute(RequestContext requestContext)
    {
        // Disable requestion validation (security) across the whole site
        ValidateRequest = false;
        base.Execute(requestContext);
    }

只要确保你是HTML编码从用户输入的视图中抽出的所有内容(无论如何,它是带有Razor的ASP.NET MVC 3中的默认行为,所以除非出于某些奇怪的原因你使用的是Html.Raw()不应该要求此功能.



22> 小智..:

我找到了一个使用JavaScript对数据进行编码的解决方案,该解决方案在.NET中解码(并且不需要jQuery).

使文本框成为HTML元素(如textarea)而不是ASP元素.

添加隐藏字段.

将以下JavaScript函数添加到标题中.

function boo(){ta​​rgetText = document.getElementById("HiddenField1"); sourceText = document.getElementById("userbox"); targetText.value = escape(sourceText.innerText); }

在你的textarea中,包含一个调用boo()的onchange:


最后,在.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
    });


});

标记:




这非常有效.如果黑客试图通过绕过JavaScript发布,他们只会看到错误.您也可以保存在数据库中编码的所有这些数据,然后将其(在服务器端)取消它,并在显示在其他地方之前解析并检查攻击.



23> woany..:

禁用页面验证,如果你真的需要像,特殊字符>,<等等.然后确保显示的用户输入时,该数据是HTML编码.

页面验证存在安全漏洞,因此可以绕过它.此外,不应仅依赖页面验证.

请参阅:http://web.archive.org/web/20080913071637/http : //www.procheckup.com : 80/ PDFs/ bypassing-dot-NET-ValidateRequest.pdf



24> Leniel Macca..:

我也得到了这个错误.

在我的例子中,用户á在角色名称中输入了重音字符(关于ASP.NET成员资格提供者).

我将角色名称传递给一个方法,以便将用户授予该角色,并且$.ajax帖子请求失败了......

我这样做是为了解决问题:

代替

data: { roleName: '@Model.RoleName', users: users }

做这个

data: { roleName: '@Html.Raw(@Model.RoleName)', users: users }

@Html.Raw 做了伎俩.

我将角色名称作为HTML值roleName="Cadastro bás".áASP.NET MVC阻止了HTML实体的这个值.现在我roleName按照应该的方式获取参数值:roleName="Cadastro Básico"ASP.NET MVC引擎不再阻止请求.



25> Trisped..:

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

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



26> 小智..:

我最终在每次回发之前使用JavaScript来检查你不想要的字符,例如:



function checkFields() {
    var tbs = new Array();
    tbs = document.getElementsByTagName("input");
    var isValid = true;
    for (i=0; i') != -1) {
                alert('<> symbols not allowed.');
                isValid = false;
            }
        }
    }
    return isValid;
}

当然,我的页面主要是数据输入,并且很少有元素可以进行回发,但至少保留了他们的数据.

推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有