JQueryを使用して、Ajaxサーバーページとして機能するASP.NETページへのajax呼び出しを行って、クエリ文字列で送信するデータを保存しています。 ASP.NETページでクエリ文字列を読み取ろうとすると、次のエラーが表示されます。
A potentially dangerous Request.QueryString value was detected from the client...
ページにValidateRequest="false"
を設定しました。すべてのページに設定する必要はありません。したがって、設定レベルではなくページレベルで行いました。
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の場合、 breaking change with ValidateRequest
がありました。 requestValidationMode
の詳細については、 このStackOverflowの質問 を参照してください。
特定のASP.NETページまたはページ全体にValidateRequest="false"
を設定せずに1つ以上のクエリ文字列パラメーターにカスタム検証ロジックを追加する場合、次の「ハッキング」ソリューションが役立ちます。
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);
}
}
このASP.NETメソッドの分析の結果として作成された正規表現: CrossSiteScriptingValidation.IsDangerousString
.NET 4.5.2でテストされたコードIIS統合モード、RequestValidationMode="2.0"
ありとなし)。
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;
}