1590 Stimmen

Ein potenziell gefährlicher Request.Form-Wert wurde vom Client erkannt

Jedes Mal, wenn ein Nutzer einen Beitrag mit < ou > in einer Seite in meiner Webanwendung, bekomme ich diese Ausnahme ausgelöst.

Ich möchte nicht in die Diskussion über die Klugheit des Auslösens einer Ausnahme oder des Absturzes einer gesamten Webanwendung gehen, weil jemand ein Zeichen in ein Textfeld eingegeben hat, aber ich suche nach einer eleganten Möglichkeit, dies zu behandeln.

Abfangen der Ausnahme und Anzeigen

Es ist ein Fehler aufgetreten. Bitte gehen Sie zurück und geben Sie das gesamte Formular noch einmal ein, aber verwenden Sie dieses Mal bitte nicht <

scheint mir nicht professionell genug zu sein.

Deaktivieren der Nachvalidierung ( validateRequest="false" ) wird dieser Fehler definitiv vermieden, aber die Seite ist dadurch anfällig für eine Reihe von Angriffen.

Idealerweise: Wenn eine Rückmeldung erfolgt, die in HTML eingeschränkte Zeichen enthält, wird der gepostete Wert in der Formularsammlung automatisch HTML-kodiert. So wird der .Text Eigenschaft meines Textfeldes wird sein something & lt; html & gt;

Gibt es eine Möglichkeit, wie ich dies von einem Handler aus tun kann?

76 Stimmen

Beachten Sie, dass dieser Fehler auch auftreten kann, wenn Sie HTML-Entitätsnamen (&) oder Entitätsnummern (') in Ihrer Eingabe haben.

32 Stimmen

Nun, da es meine Frage ist, glaube ich, dass ich definieren kann, worum es eigentlich geht: einen ganzen Anwendungsprozess zum Absturz zu bringen und eine allgemeine Fehlermeldung auszugeben, weil jemand ein "<" eingegeben hat, ist übertrieben. Vor allem, weil man weiß, dass die meisten Leute einfach 'validateRequest=false' eingeben werden, um es loszuwerden, und damit die Schwachstelle wieder aufreißen

10 Stimmen

@DrewNoakes: Entitätsnamen (&) scheinen nach meinen Tests (getestet in .Net 4.0) kein Problem zu sein, obwohl Entitätsnummern (') die Validierung nicht bestehen (wie Sie sagten). Wenn Sie die Methode System.Web.CrossSiteScriptingValidation.IsDangerousString mit dem .Net Reflector zerlegen, werden Sie sehen, dass der Code speziell nach html-Tags (beginnend mit <) und Entity-Nummern (beginnend mit &#) sucht

7voto

Ryan Punkte 71

Ich endete mit JavaScript vor jedem Postback, um nach den Zeichen zu suchen, die Sie nicht wollen, wie z. B.:

<asp:Button runat="server" ID="saveButton" Text="Save" CssClass="saveButton" OnClientClick="return checkFields()" />

function checkFields() {
    var tbs = new Array();
    tbs = document.getElementsByTagName("input");
    var isValid = true;
    for (i=0; i<tbs.length; i++) {
        if (tbs(i).type == 'text') {
            if (tbs(i).value.indexOf('<') != -1 || tbs(i).value.indexOf('>') != -1) {
                alert('<> symbols not allowed.');
                isValid = false;
            }
        }
    }
    return isValid;
}

Zugegeben, meine Seite besteht größtenteils aus Dateneingabe, und es gibt nur sehr wenige Elemente, die Postbacks durchführen, aber zumindest werden ihre Daten beibehalten.

0 Stimmen

Es sollten große Klammern anstelle von kleinen Klammern verwendet werden. Zum Beispiel ` if (tbs[i].type == 'text') {` anstelle von ` if (tbs(i).type == 'text') {`

6voto

Ady Levy Punkte 151

Sie können etwas verwenden wie:

var nvc = Request.Unvalidated().Form;

Später, nvc["yourKey"] sollte funktionieren.

0 Stimmen

Danke, Ihre Antwort hat mir eine Menge Zeit erspart.

6voto

Sel Punkte 1834

Sie können Felder in benutzerdefinierten Modellbindern automatisch mit HTML kodieren. Meine Lösung ist etwas anders, ich setze den Fehler in ModelState und zeige die Fehlermeldung neben dem Feld an. Es ist einfach, diesen Code für die automatische Kodierung zu ändern

 public class AppModelBinder : DefaultModelBinder
    {
        protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
        {
            try
            {
                return base.CreateModel(controllerContext, bindingContext, modelType);
            }
            catch (HttpRequestValidationException e)
            {
                HandleHttpRequestValidationException(bindingContext, e);
                return null; // Encode here
            }
        }
        protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext,
            PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
        {
            try
            {
                return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
            }
            catch (HttpRequestValidationException e)
            {
                HandleHttpRequestValidationException(bindingContext, e);
                return null; // Encode here
            }
        }

        protected void HandleHttpRequestValidationException(ModelBindingContext bindingContext, HttpRequestValidationException ex)
        {
            var valueProviderCollection = bindingContext.ValueProvider as ValueProviderCollection;
            if (valueProviderCollection != null)
            {
                ValueProviderResult valueProviderResult = valueProviderCollection.GetValue(bindingContext.ModelName, skipValidation: true);
                bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
            }

            string errorMessage = string.Format(CultureInfo.CurrentCulture, "{0} contains invalid symbols: <, &",
                     bindingContext.ModelMetadata.DisplayName);

            bindingContext.ModelState.AddModelError(bindingContext.ModelName, errorMessage);
        }
    }

In Anwendung_Start:

ModelBinders.Binders.DefaultBinder = new AppModelBinder();

Beachten Sie, dass dies nur für Formularfelder funktioniert. Der gefährliche Wert wird nicht an das Controller-Modell übergeben, sondern in ModelState gespeichert und kann im Formular mit einer Fehlermeldung erneut angezeigt werden.

Gefährliche Zeichen in der URL können auf diese Weise behandelt werden:

private void Application_Error(object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    HttpContext httpContext = HttpContext.Current;

    HttpException httpException = exception as HttpException;
    if (httpException != null)
    {
        RouteData routeData = new RouteData();
        routeData.Values.Add("controller", "Error");
        var httpCode = httpException.GetHttpCode();
        switch (httpCode)
        {
            case (int)HttpStatusCode.BadRequest /* 400 */:
                if (httpException.Message.Contains("Request.Path"))
                {
                    httpContext.Response.Clear();
                    RequestContext requestContext = new RequestContext(new HttpContextWrapper(Context), routeData);
                    requestContext.RouteData.Values["action"] ="InvalidUrl";
                    requestContext.RouteData.Values["controller"] ="Error";
                    IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
                    IController controller = factory.CreateController(requestContext, "Error");
                    controller.Execute(requestContext);
                    httpContext.Server.ClearError();
                    Response.StatusCode = (int)HttpStatusCode.BadRequest /* 400 */;
                }
                break;
        }
    }
}

ErrorController:

public class ErrorController : Controller
 {
   public ActionResult InvalidUrl()
   {
      return View();
   }
}

0 Stimmen

Ich bin nur hierher gekommen, um das zu posten. Schade, dass es für immer auf der zweiten Seite vergraben bleiben wird - das ist, IMHO, die beste Lösung.

6voto

Wahid Masud Punkte 923

Für diejenigen, die keine Modellbindung verwenden, die jeden Parameter aus dem Request.Form extrahieren und die sicher sind, dass der Eingabetext keinen Schaden anrichten wird, gibt es einen anderen Weg. Keine großartige Lösung, aber sie erfüllt ihre Aufgabe.

Auf der Client-Seite kodieren Sie es als uri und senden es dann.
z.B.:

encodeURIComponent($("#MsgBody").val());  

Auf der Serverseite wird sie akzeptiert und als uri dekodiert.
z.B.:

string temp = !string.IsNullOrEmpty(HttpContext.Current.Request.Form["MsgBody"]) ?
System.Web.HttpUtility.UrlDecode(HttpContext.Current.Request.Form["MsgBody"]) : 
null;  

ou

string temp = !string.IsNullOrEmpty(HttpContext.Current.Request.Form["MsgBody"]) ?
System.Uri.UnescapeDataString(HttpContext.Current.Request.Form["MsgBody"]) : 
null; 

suchen Sie bitte nach den Unterschieden zwischen UrlDecode y UnescapeDataString

5voto

Captain Toad Punkte 331

Wenn Sie Ihren Benutzern nur sagen wollen, dass < und > nicht verwendet werden dürfen, ABER Sie nicht wollen, dass das gesamte Formular verarbeitet/zurückgeschickt wird (und alle Eingaben verloren gehen), könnten Sie nicht einfach einen Validator um das Feld herum einbauen, um nach diesen (und vielleicht anderen potenziell gefährlichen) Zeichen zu suchen?

0 Stimmen

Bitte besagten "Validator" posten

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X