从jquery post调用asp.net页面发送html标记时,客户端检测到潜在危险的Request.QueryString值
我使用jQuery的ajax调用一个ASP.NET页面作为我的ajax服务器页面来保存我发送到查询string中的数据。 在ASP.NET页面中,当我正在阅读querystring我得到这个错误:
A potentially dangerous Request.QueryString value was detected from the client...
我在页面中设置了ValidateRequest="false"
。 不想为所有页面设置它。 所以在页面级别而不是configuration级别:
var content = "<h3>Sample header</h3><p>sample para</p>" content = encodeURIComponent(content); var url = "../Lib/ajaxhandler.aspx?mode=savecontent&page=home<xt=" + content; $.post(url, function (data) { //check return value and do something });
并在我的asp.net页面:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ajaxhandler.aspx.cs" ValidateRequest="false" Inherits="MyProject.Lib.ajaxhandler" %>
但是,当我发送纯文本,而不是HTML标记,它工作正常。
如果这是ASP.NET 4,那么ValidateRequest
发生了重大变化 。 有关requestValidationMode
更多信息,请参阅此StackOverflow问题 。
已经有一个很好的答案了,在这里我会提供信息,所以你不必点击链接。
运行ASP.NET 4.0时,需要在web.config文件中设置以下参数: RequestValidationMode="2.0"
。
这个属性是什么?
指示将使用哪个ASP.NET版本特定的validation方法的值。 默认值是4.0。
那么可能的价值是什么?
-
4.0(默认)。 HttpRequest对象在内部设置一个标志,指示请求validation应该随时触发
HTTP请求数据被访问。 这保证了请求
validation在数据(例如cookie和URL)被触发之前触发
在请求期间被访问。 请求validation设置的
pages元素(如果有)在configuration文件或@ Page中
单个页面中的指令被忽略。 -
2.0。 请求validation仅针对页面启用,而不针对所有HTTP请求。 另外,configuration文件中页面元素(如果有)的请求validation设置或单个页面中的@ Page指令的请求validation设置用于确定要validation哪些页面请求。
从这个msdn网站引用的信息。
如果您想为一个特定的ASP.NET页面或一个或多个查询string参数添加自定义validation逻辑,而不必为整个页面设置ValidateRequest="false"
,则下面的“hacky”解决scheme可能会有用:
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, "(\\<+[az!/\\?])|(&\\#)", 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); } }
由此ASP.NET方法分析的正则expression式: CrossSiteScriptingValidation.IsDangerousString
代码testing与.NET 4.5.2,IIS集成模式,有和没有RequestValidationMode="2.0"
。
在asp页面的顶部设置ValidateRequest =“false”。
我根据VAV的答案创build了一些可重复使用的方法
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, "(\\<+[az!/\\?])|(&\\#)", new MatchEvaluator((m) => { return m.Value.Replace("<", valueToReplace).Replace("&#", valueToReplace); }), RegexOptions.IgnoreCase); } return unvalidatedValue; }