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

22voto

Sel Punkte 1834

Eine andere Lösung ist:

protected void Application_Start()
{
    ...
    RequestValidator.Current = new MyRequestValidator();
}

public class MyRequestValidator: RequestValidator
{
    protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
    {
        bool result = base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);

        if (!result)
        {
            // Write your validation here
            if (requestValidationSource == RequestValidationSource.Form ||
                requestValidationSource == RequestValidationSource.QueryString)

                return true; // Suppress error message
        }
        return result;
    }
}

0 Stimmen

Toll! Mir war nicht bewusst, dass man den Request Validator ersetzen kann. Anstatt einfach "ok" zu sagen, wie Sie es tun, habe ich diese Idee erweitert, um Felder, deren Name auf "_NoValidation" endet, nicht zu validieren. Code unten.

0 Stimmen

Walden Leverich, siehe dazu [AllowHtml]-Attribut

0 Stimmen

Sel, ja in einer MVC-Umgebung, die funktionieren würde. Aber in einer Webforms-Anwendung habe ich kein Modell, um das zu tun :-)

15voto

blowdart Punkte 53842

Ich schätze, man könnte es in einem Modul machen; aber das lässt einige Fragen offen; was ist, wenn man die Eingabe in einer Datenbank speichern will? Plötzlich, weil Sie kodierte Daten in der Datenbank speichern, müssen Sie sich auf die Eingabe verlassen, was wahrscheinlich eine schlechte Idee ist. Idealerweise speichert man unkodierte Rohdaten in der Datenbank und kodiert sie jedes Mal.

Es ist besser, den Schutz für jede einzelne Seite zu deaktivieren und dann jedes Mal zu kodieren.

Anstatt Server.HtmlEncode zu verwenden, sollten Sie sich das neuere, vollständigere Anti-XSS-Bibliothek vom Microsoft ACE-Team.

15voto

Durgesh Pandey Punkte 2076

Wenn Sie Framework 4.0 verwenden, muss der Eintrag in der web.config (<pages validateRequest="false" />)

<configuration>
    <system.web>
        <pages validateRequest="false" />
    </system.web>
</configuration>

Wenn Sie Framework 4.5 verwenden, muss der Eintrag in der web.config (requestValidationMode="2.0")

<system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" requestValidationMode="2.0"/>
</system.web>

Wenn Sie für nur eine Seite dann wollen, in Sie aspx-Datei sollten Sie die erste Zeile als diese setzen:

<%@ Page EnableEventValidation="false" %>

wenn Sie bereits etwas wie <%@ Seite haben, fügen Sie einfach den Rest hinzu => EnableEventValidation="false" %>

Ich empfehle, dies nicht zu tun.

14voto

Jaider Punkte 13198

In ASP.NET können Sie die Ausnahme abfangen und etwas dagegen tun, z. B. eine freundliche Meldung anzeigen oder auf eine andere Seite umleiten... Es besteht auch die Möglichkeit, dass Sie die Validierung selbst durchführen können...

Freundliche Nachricht anzeigen:

protected override void OnError(EventArgs e)
{
    base.OnError(e);
    var ex = Server.GetLastError().GetBaseException();
    if (ex is System.Web.HttpRequestValidationException)
    {
        Response.Clear();
        Response.Write("Invalid characters."); //  Response.Write(HttpUtility.HtmlEncode(ex.Message));
        Response.StatusCode = 200;
        Response.End();
    }
}

12voto

Jason Shuler Punkte 374

Ich habe eine Lösung gefunden, die JavaScript zur Kodierung der Daten verwendet, die in .NET dekodiert werden (und kein jQuery erfordern).

  • Machen Sie das Textfeld zu einem HTML-Element (wie textarea) und nicht zu einem ASP-Element.
  • Fügen Sie ein verborgenes Feld hinzu.
  • Fügen Sie die folgende JavaScript-Funktion in Ihre Kopfzeile ein.

    Funktion boo() { targetText = document.getElementById("HiddenField1"); sourceText = document.getElementById("userbox"); targetText.value = escape(sourceText.innerText); }

Fügen Sie in Ihre Textarea ein onchange ein, das boo() aufruft:

<textarea id="userbox"  onchange="boo();"></textarea>

Schließlich, in .NET, verwenden Sie

string val = Server.UrlDecode(HiddenField1.Value);

Ich bin mir bewusst, dass dies eine Einweglösung ist - wenn Sie eine Zweiweglösung benötigen, müssen Sie kreativ werden, aber dies ist eine Lösung, wenn Sie die web.config nicht bearbeiten können

Hier ist ein Beispiel ich (MC9000) kam mit und verwenden Sie über jQuery:

$(document).ready(function () {

    $("#txtHTML").change(function () {
        var currentText = $("#txtHTML").text();
        currentText = escape(currentText); // Escapes the HTML including quotations, etc
        $("#hidHTML").val(currentText); // Set the hidden field
    });

    // Intercept the postback
    $("#btnMyPostbackButton").click(function () {
        $("#txtHTML").val(""); // Clear the textarea before POSTing
                               // If you don't clear it, it will give you
                               // the error due to the HTML in the textarea.
        return true; // Post back
    });

});

Und der Aufschlag:

<asp:HiddenField ID="hidHTML" runat="server" />
<textarea id="txtHTML"></textarea>
<asp:Button ID="btnMyPostbackButton" runat="server" Text="Post Form" />

Das funktioniert hervorragend. Wenn ein Hacker versucht, unter Umgehung von JavaScript einen Beitrag zu verfassen, wird er nur eine Fehlermeldung sehen. Sie können all diese Daten auch verschlüsselt in einer Datenbank speichern, sie dann (auf der Serverseite) entschlüsseln und auf Angriffe prüfen, bevor sie an anderer Stelle angezeigt werden.

0 Stimmen

Das ist eine gute Lösung. Es ist ein guter manueller Weg, um es selbst zu kontrollieren und nicht die gesamte Website oder Seite ungültig zu machen

0 Stimmen

Stellen Sie sicher, dass Sie ein HTML-Markup und kein ASP.Net-Steuerelement (d.h. kein runat="server") für die Textarea verwenden, und verwenden Sie dann das versteckte ASP.Net-Steuerelement für das Versteckte. Dies ist die beste Lösung, die ich gesehen habe, ohne Kompromisse zu machen. Natürlich wollen Sie Ihre Daten für XSS, SQL Injection auf der Server-Seite zu analysieren, aber zumindest können Sie posten HTML

0 Stimmen

escape(...) kann sehr lange dauern. In meinem Fall war das Markup eine ganze (2MB) XML-Datei. Sie könnten fragen: "Warum verwenden Sie nicht einfach <input type="file"... und ... Ich stimme mit Ihnen überein :)

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