2017-03-09 16 views
1

iは、次の問題取り扱いと

に対処しようとしているこのエラーの通知ユーザーの潜在的に危険のRequest.Form値がクライアントから検出された '「潜在的に危険のRequest.Form値が検出されましたから、 クライアント '

しかし、私はこのエラーをキャッチして処理する方法を説明する良いチュートリアルを見つけることができません。私のフォームに記入する際にユーザーがマークアップを入力するのを止めたいのです。この問題を扱う記事のほとんどは、要求の検証を無効にすることを提案しています。これは私がしたいことではありません。私はエラーをキャッチし、ユーザーにエラーを再生したい。どんな助けでも大歓迎です。

+0

おそらく、HTMLを許可する方が簡単ですが、入力値からマークアップを取り除くだけでしょうか? –

+0

@TiesonT。 *たくさんのものがあります/この検証によって除外されるさまざまな攻撃 - ASP.Netよりも優れていると思っているのは素朴です。 – caesay

+0

@caesayリクエストの検証を無効にすることはお勧めしません。 OPが使用しているモデルにAllowHtmlAttributeを追加し、入力をサニタイズすることをお勧めします。 –

答えて

2

例外フィルタでエラーをキャッチできます。ような何か:

public class RequestValidationExceptionFilter : IExceptionFilter 
{ 
    public void OnException(ExceptionContext filterContext) 
    { 
     if(filterContext.Exception is HttpRequestValidationException) 
     { 
      filterContext.Result = new RedirectResult("/Error"); 
      filterContext.ExceptionHandled = true; 
     } 
    } 
} 

あなたは例外のMessageでいくつかの詳細情報を取得することができ、例えば:

潜在的に危険な場合、Request.QueryString値はFILTERNAME =」<スクリプト(クライアントから検出された>警告( "!!")< ... ")。

しかし、これは実際にユーザーに表示されるものではありません。だから、最も一般的なエラーページへのリダイレクトがあります。または、それらを現在のページに戻すことができます。

+0

私はこのエラーをユーザーに再生することができるように、モデルステートにエラーを追加する方法はありますか?しかし、私はより一般的なエラーメッセージを作成します。 – tbonejenkins

+0

さて、例外フィルタのこの時点では、すでにコントローラから外れています。だから私はそうは思わない。エラーをスローするコンポーネントを置き換えることができた場合は、おそらくmodelstateにエラーを追加することができます。 – juunas

+0

エラーがスローされる前にアクションフィルタが実行され、内部的に使用するのと同じコンポーネントで検証できます。 modelstateエラーを返し、モデルの値を消去して、エラーがスローされないようにします。しかし、モデルバインド中にスローされた場合、これは動作しません.. – juunas

0

私はすぐにいくつかの理由で何かの理由でアクションフィルタと例外フィルタが実行されていなかったので、検証例外が起きていないので、すぐにApplication_Error()を使って何かを起草しました。私は、任意のURLにリダイレクトする方法の例、また、同じコントローラに対して新しいActionResultを実行する方法の例を含め

protected void Application_Error() 
{ 
    var lastError = Server.GetLastError() as HttpRequestValidationException; 
    if (lastError == null) 
     return; 

    MvcHandler mvcHandler = Context.CurrentHandler as MvcHandler; 
    if (mvcHandler == null) 
     return; 

    RequestContext requestContext = mvcHandler.RequestContext; 
    if (requestContext == null) 
     return; 

    Server.ClearError(); 
    Response.Clear(); 
    Response.TrySkipIisCustomErrors = true; 

    // pick one of the following two options, or maybe more? 
    RedirectToUrl(requestContext); 
    ExecuteActionResult(requestContext, ...); 

} 

void ExecuteActionResult(RequestContext requestContext, ActionResult result) 
{ 
    string controllerName = requestContext.RouteData.GetRequiredString("controller"); 
    IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory(); 
    IController controller = factory.CreateController(requestContext, controllerName); 
    ControllerContext controllerContext = new ControllerContext(requestContext, (ControllerBase)controller); 
    result.ExecuteResult(controllerContext); 
} 

void RedirectToUrl(RequestContext requestContext) 
{ 
    requestContext.HttpContext.Server.TransferRequest($"~/Error/Something", false); 
} 

(それがまだ存在していない場合、あなたはGlobal.asax.csでこのメソッドを作成することができます)元の要求が実行されたことを示します。