将 html 标记从 jquery post 调用发送到 asp.net 页面时,从客户端检测到潜在危险的 Request.QueryString 值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3885697/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 16:16:33  来源:igfitidea点击:

A potentially dangerous Request.QueryString value was detected from the client when sending html markup from jquery post call to asp.net page

asp.netjqueryajaxsecurityasp.net-ajax

提问by Shyju

I m making an ajax call using jQuery to an ASP.NET page which acts as my ajax server page to save the data which i am sending to it in the query string. In the ASP.NET page when i am trying to read the querystring i am getting this error:

我正在使用 jQuery 对 ASP.NET 页面进行 ajax 调用,该页面充当我的 ajax 服务器页面以保存我在查询字符串中发送给它的数据。在 ASP.NET 页面中,当我尝试读取查询字符串时,出现此错误:

A potentially dangerous Request.QueryString value was detected from the client...

I have set the ValidateRequest="false"in my page. Dont want to set it for all the pages. So did it in page level instead of config level:

我已经ValidateRequest="false"在我的页面中设置了 。不想为所有页面设置它。在页面级别而不是配置级别这样做:

  var content = "<h3>Sample header</h3><p>sample para</p>"
  content = encodeURIComponent(content);
  var url = "../Lib/ajaxhandler.aspx?mode=savecontent&page=home&ltxt=" + content;

     $.post(url, function (data) { 
       //check return value and do something
   });

and in my asp.net page:

在我的 asp.net 页面中:

 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ajaxhandler.aspx.cs" ValidateRequest="false" Inherits="MyProject.Lib.ajaxhandler" %>

But when i am sending plain text instead of the html markup, it works fine.

但是当我发送纯文本而不是 html 标记时,它工作正常。

采纳答案by Forgotten Semicolon

If this is ASP.NET 4, there was a breaking changewith ValidateRequest. See this StackOverflow questionfor more information on requestValidationMode.

如果这是ASP.NET 4,有一个重大更改ValidateRequest。有关的更多信息,请参阅此 StackOverflow 问题requestValidationMode

回答by Jim Aho

There's already a good answer for this, and here i'll provide the information so that you don't have to click through links.

对此已经有一个很好的答案,在这里我将提供信息,以便您不必单击链接。

When running ASP.NET 4.0, you will need to set the following in your web.config file RequestValidationMode="2.0".

运行 ASP.NET 4.0 时,您需要在 web.config 文件中设置以下内容RequestValidationMode="2.0"

What is this property for?

这个属性有什么用?

A value that indicates which ASP.NET version-specific approach to validation will be used. The default is 4.0.

一个值,指示将使用哪种 ASP.NET 特定于版本的验证方法。默认值为 4.0。

So what are the possible values?

那么可能的值是什么?

  • 4.0 (the default). The HttpRequest object internally sets a flag that indicates that request validation should be triggered whenever any
    HTTP request data is accessed. This guarantees that the request
    validation is triggered before data such as cookies and URLs are
    accessed during the request. The request validation settings of the
    pages element (if any) in the configuration file or of the @ Page
    directive in an individual page are ignored.

  • 2.0. Request validation is enabled only for pages, not for all HTTP requests. In addition, the request validation settings of the pages element (if any) in the configuration file or of the @ Page directive in an individual page are used to determine which page requests to validate.

  • 4.0(默认)。HttpRequest 对象在内部设置了一个标志,指示每当
    访问任何HTTP 请求数据时都应触发请求验证。这保证在请求 期间访问
    cookie 和 URL 等数据之前触发请求验证

    配置文件中的pages 元素(如果有)或
    单个页面中的 @ Page指令的请求验证设置将被忽略。

  • 2.0. 仅对页面启用请求验证,而不对所有 HTTP 请求启用。此外,配置文件中的 pages 元素(如果有)或单个页面中的 @Page 指令的请求验证设置用于确定要验证哪些页面请求。

Information citated from this msdn site.从这个 msdn 站点引用的信息。

回答by VAV

If you want to add a custom validation logic for one particular ASP.NET page or for one or more query string parameters without setting ValidateRequest="false"for entire page - the following "hacky" solution could be useful:

如果您想为一个特定的 ASP.NET 页面或一个或多个查询字符串参数添加自定义验证逻辑而不ValidateRequest="false"为整个页面设置- 以下“hacky”解决方案可能很有用:

public partial class MyPage : System.Web.UI.Page
{
    private string SomeUnvalidatedValue { get; set; }

    public override void ProcessRequest(HttpContext context)
    {
        var queryString = context.Request.QueryString;

        var readOnly = queryString.GetType().GetProperty("IsReadOnly",
            System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

        readOnly.SetValue(queryString, false);

        var unvalidatedValue = context.Request.Unvalidated.QueryString["SomeKey"];
        // for RequestValidationMode="2.0"
        //var unvalidatedValue = context.Request.QueryString["SomeKey"];

        // custom logic goes here

        // you could store unvalidated value here and then remove it from the query string
        SomeUnvalidatedValue = unvalidatedValue;
        queryString["SomeKey"] = string.Empty;
        // or just remove all "potentially dangerous" symbols, for example
        if (!string.IsNullOrEmpty(unvalidatedValue))
        {
            queryString["SomeKey"] = Regex.Replace(unvalidatedValue,
                "(\<+[a-z!/\?])|(&\#)", new MatchEvaluator((m) =>
                {
                    return m.Value.Replace("<", string.Empty).Replace("&#", string.Empty);
                }), RegexOptions.IgnoreCase);
        }

        readOnly.SetValue(queryString, true);

        // keep other request validation logic as is
        base.ProcessRequest(context);
    }
}

The regular expression made as result of this ASP.NET method analyzing: CrossSiteScriptingValidation.IsDangerousString

作为此 ASP.NET 方法分析结果的正则表达式:CrossSiteScriptingValidation.IsDangerousString

Code tested with .NET 4.5.2, IIS integrated mode, with and without RequestValidationMode="2.0".

使用 .NET 4.5.2、IIS 集成模式测试的代码,带和不带RequestValidationMode="2.0".

回答by Michael Freidgeim

I've created a couple reusable methods based on VAV's answer

我根据VAV 的回答创建了几个可重用的方法

   public static string ExtractUnvalidatedValue(HttpRequest request, string key)
        {
            var unvalidatedValue =  HttpUtility.UrlDecode(request.Unvalidated.QueryString[key]);
            // for RequestValidationMode="2.0"
            //var unvalidatedValue = context.Request.QueryString["SomeKey"];

          // remove all "potentially dangerous" symbols
            return ReplacePotentiallyDangerousSymbols(unvalidatedValue, string.Empty);
        }

    public static string ReplacePotentiallyDangerousSymbols(string unvalidatedValue, string valueToReplace="")
        {
            if (!string.IsNullOrEmpty(unvalidatedValue))
            {
                //The regular expression made as result of this ASP.NET method analyzing: CrossSiteScriptingValidation.IsDangerousString http://referencesource.microsoft.com/#System.Web/CrossSiteScriptingValidation.cs,3c599cea73c5293b
                unvalidatedValue = Regex.Replace(unvalidatedValue,
                    "(\<+[a-z!/\?])|(&\#)",
                    new MatchEvaluator((m) => { return m.Value.Replace("<", valueToReplace).Replace("&#", valueToReplace); }), RegexOptions.IgnoreCase);
            }
            return unvalidatedValue;
        }

回答by Deepu R Nair

set ValidateRequest="false" on the top of the asp page.

在asp页面的顶部设置ValidateRequest="false"。