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
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:
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
Code tested with .NET 4.5.2, IIS integrated mode, with and without RequestValidationMode="2.0".