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

1471

Jedes Mal, wenn ein Benutzer etwas in meiner Webanwendung veröffentlicht, das etwas enthält <oder >auf einer Seite steht, wird diese Ausnahme ausgelöst.

Ich möchte nicht auf die Diskussion eingehen, wie intelligent es ist, eine Ausnahme auszulösen oder eine gesamte Webanwendung zum Absturz zu bringen, weil jemand ein Zeichen in ein Textfeld eingegeben hat, aber ich suche nach einer eleganten Möglichkeit, damit umzugehen.

Die Ausnahme abfangen und anzeigen

Es ist ein Fehler aufgetreten. Bitte gehen Sie zurück und geben Sie Ihr gesamtes Formular erneut ein. Verwenden Sie diesmal jedoch nicht <

scheint mir nicht professionell genug zu sein.

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

Idealerweise: Wenn ein Postback mit HTML-beschränkten Zeichen erfolgt, wird der in der Formularsammlung veröffentlichte Wert automatisch HTML-codiert. So wird die .TextEigenschaft meines Textfeldes seinsomething & lt; html & gt;

Gibt es eine Möglichkeit, dies von einem Handler aus zu tun?

Radu094
quelle
68
Beachten Sie, dass Sie diesen Fehler erhalten können, wenn Sie auch HTML-Entitätsnamen (& amp;) oder Entitätsnummern (& # 39;) in Ihrer Eingabe haben.
Drew Noakes
18
Nun, da es meine Frage ist, kann ich definieren, worum es eigentlich geht: Einen gesamten Bewerbungsprozess zum Absturz zu bringen und eine generische Fehlermeldung zurückzugeben, weil jemand ein '<' eingegeben hat, ist übertrieben. Zumal Sie wissen, dass die meisten Leute nur 'validateRequest = false' verwenden, um es loszuwerden, wodurch die Sicherheitslücke wieder
geöffnet wird
7
@DrewNoakes: Entitätsnamen (& amp;) scheinen nach meinen Tests (getestet in .Net 4.0) kein Problem zu sein, obwohl Entitätsnummern (& # 39;) die Validierung nicht bestehen (wie Sie sagten). Wenn Sie die System.Web.CrossSiteScriptingValidation.IsDangerousString-Methode mit .Net Reflector zerlegen, werden Sie feststellen, dass der Code speziell nach HTML-Tags (beginnend mit <) und Entitätsnummern (beginnend mit & #)
sucht
5
Erstellen Sie eine neue Site in VS2014 mit dem Standard-MVC-Projekt und führen Sie es aus. Klicken Sie auf den Link zum Registrieren, fügen Sie eine E-Mail hinzu und verwenden Sie "<P455-0r [!" als Passwort. Der gleiche Fehler ist sofort einsatzbereit, da nicht versucht wird, etwas Bösartiges zu tun. Das Kennwortfeld wird nicht angezeigt, sodass es sich nicht um einen XSS-Angriff handelt. Die einzige Möglichkeit, ihn zu beheben, besteht darin, die Überprüfung mit dem ValidateInput (false) vollständig zu entfernen. ? Der AllowHtml-Vorschlag funktioniert in dieser Situation nicht und ist immer noch mit demselben Fehler aufgetreten. Ein möglicherweise gefährlicher Request.Form-Wert wurde vom Client erkannt (Password = "<P455-0r [!").
Stephenbayer
TL; DR <httpRuntime requestValidationMode="2.0" />in web.config

Antworten:

1080

Ich denke, Sie greifen es aus dem falschen Blickwinkel an, indem Sie versuchen, alle veröffentlichten Daten zu verschlüsseln.

Beachten Sie, dass ein " <" auch von anderen externen Quellen stammen kann, z. B. einem Datenbankfeld, einer Konfiguration, einer Datei, einem Feed usw.

Darüber hinaus ist " <" nicht von Natur aus gefährlich. Dies ist nur in einem bestimmten Kontext gefährlich: beim Schreiben von Zeichenfolgen, die nicht in die HTML-Ausgabe codiert wurden (aufgrund von XSS).

In anderen Kontexten sind andere Unterzeichenfolgen gefährlich. Wenn Sie beispielsweise eine vom Benutzer angegebene URL in einen Link schreiben, kann die Unterzeichenfolge " javascript:" gefährlich sein. Das einfache Anführungszeichen hingegen ist beim Interpolieren von Zeichenfolgen in SQL-Abfragen gefährlich, aber absolut sicher, wenn es Teil eines Namens ist, der aus einem Formular gesendet oder aus einem Datenbankfeld gelesen wurde.

Das Fazit lautet: Sie können keine zufälligen Eingaben nach gefährlichen Zeichen filtern, da jedes Zeichen unter den richtigen Umständen gefährlich sein kann. Sie sollten an der Stelle codieren, an der bestimmte Zeichen gefährlich werden können, weil sie in eine andere Subsprache übergehen, in der sie eine besondere Bedeutung haben. Wenn Sie eine Zeichenfolge in HTML schreiben, sollten Sie mit Server.HtmlEncode Zeichen codieren, die in HTML eine besondere Bedeutung haben. Wenn Sie eine Zeichenfolge an eine dynamische SQL-Anweisung übergeben, sollten Sie verschiedene Zeichen codieren (oder besser, lassen Sie das Framework dies für Sie tun, indem Sie vorbereitete Anweisungen oder ähnliches verwenden).

Wenn Sie sicher sind, dass Sie überall HTML-codieren, übergeben Sie Zeichenfolgen an HTML, und legen Sie validateRequest="false"die <%@ Page ... %>Anweisung in Ihren .aspxDateien fest.

In .NET 4 müssen Sie möglicherweise etwas mehr tun. Manchmal ist es notwendig, auch <httpRuntime requestValidationMode="2.0" />web.config ( Referenz ) hinzuzufügen .

JacquesB
quelle
74
Für diejenigen, die zu spät kommen: validateRequest = "false" steht in der Page-Direktive (erste Zeile Ihrer ASPX-Datei)
MGOwen
56
Tipp: Fügen Sie <httpRuntime requestValidationMode="2.0" />ein Standort-Tag ein, um zu vermeiden, dass der nützliche Schutz, der durch die Validierung durch den Rest Ihrer Site bereitgestellt wird, beeinträchtigt wird.
Brian
297
In MVC3 befindet sich dies [AllowHtml]in der Modelleigenschaft.
Jeremy Holovacs
2
Um es global für MVC 3 zu deaktivieren, benötigen Sie auch GlobalFilters.Filters.Add(new ValidateInputAttribute(false));in Application_Start().
Alex
15
@MGOwen Sie können die Seitenanweisung auch über <pages validateRequest="false" />in zur web.config hinzufügen <system.web />. Dadurch wird die Eigenschaft auf alle Seiten angewendet.
Oliver-Clare
504

Es gibt eine andere Lösung für diesen Fehler, wenn Sie ASP.NET MVC verwenden:

C # Beispiel:

[HttpPost, ValidateInput(false)]
public ActionResult Edit(FormCollection collection)
{
    // ...
}

Visual Basic-Beispiel:

<AcceptVerbs(HttpVerbs.Post), ValidateInput(False)> _
Function Edit(ByVal collection As FormCollection) As ActionResult
    ...
End Function
Zack Peterson
quelle
Das Problem kann auftreten, wenn es auf einer Seite der gesamten Anwendung benötigt wird
3
Sie können das Attribut [ValidateInput (false)] auch auf Klassenebene hinzufügen. Wenn Sie es Ihrer Basis-Controller-Klasse hinzufügen, gilt es für alle Controller-Methodenaktionen.
Shan Plourde
@Zack Danke für die Lösung. Auf der anderen Seite frage ich mich, ob [AllowHtml]es besser ist als ValidateInput(false), weil [AllowHtml]es sofort für eine Eigenschaft definiert ist, dh für ein Editor-Feld, und wenn es verwendet wird, muss es nicht für mehrere Aktionen verwendet werden. Was schlagen Sie vor?
Jack
@Zack Peterson Ist die Verwendung sicher? Kein Sicherheitsproblem?
Shrey Pav
416

In ASP.NET MVC (ab Version 3) können Sie das AllowHtmlAttribut einer Eigenschaft in Ihrem Modell hinzufügen .

Es ermöglicht einer Anforderung, HTML-Markup während der Modellbindung einzuschließen, indem die Anforderungsüberprüfung für die Eigenschaft übersprungen wird.

[AllowHtml]
public string Description { get; set; }
Anthony Johnston
quelle
12
Viel besser deklarativ als im Controller!
Andiih
29
Die einzig richtige Antwort! Das Deaktivieren der Validierung für Controller-Aktionen ist hacky. Und um die Validierung auf Anwendungsebene zu deaktivieren, müssen Entwickler gehängt werden!
Trailmax
Ist dies in MVC 4 verschwunden?
GranadaCoder
1
Was ist der Unterschied zwischen ValidateInput(false)und AllowHtml? Was ist der Vorteil von einem gegenüber dem anderen? Wann möchte ich AllowHtmlanstelle von verwenden ValidateInput(false)? Wann würde ich verwenden soll ValidateInput(false)über AllowHtml? Wann möchte ich beide verwenden? Ist es sinnvoll, beide zu verwenden?
Ian Boyd
3
ValidateInput befindet sich in der Methode, AllowHtml befindet sich in der Eigenschaft des Modells - Sie erlauben also nur denjenigen, von dem Sie erwarten, dass er HTML hat - nicht alle
Anthony Johnston
213

Wenn Sie mit .NET 4.0 arbeiten, stellen Sie sicher, dass Sie dies in Ihrer web.config- Datei innerhalb der <system.web>Tags hinzufügen :

<httpRuntime requestValidationMode="2.0" />

In .NET 2.0 wurde die Anforderungsüberprüfung nur auf aspxAnforderungen angewendet . In .NET 4.0 wurde dies um alle Anforderungen erweitert. Sie können bei der Verarbeitung nur die XSS-Validierung durchführen, .aspxindem Sie Folgendes angeben:

requestValidationMode="2.0"

Sie können die Validierung von Anforderungen vollständig deaktivieren, indem Sie Folgendes angeben:

validateRequest="false"
JordanC
quelle
30
Innerhalb der <system.web>Tags.
Hosam Aly
8
Ich habe dies in die web.config gestellt, aber immer noch auf den Fehler "Ein potenziell gefährlicher Request.Form-Wert"
Filip
20
<HttpRuntime requestValidationMode = "2.0" /> funktioniert anscheinend nur, wenn das 2.0-Framework auf dem Computer installiert ist. Was ist, wenn das 2.0-Framework überhaupt nicht installiert ist, sondern nur das 4.0-Framework installiert ist?
Samuel
Das hat bei mir total geklappt. Keines der Schritte Dokument in den anderen Antworten war notwendig (einschließlich validateRequest = "false")!
Tom Redfern
112

In ASP.NET 4.0 können Sie Markups als Eingabe für bestimmte Seiten anstelle der gesamten Site zulassen, indem Sie alles in ein <location>Element einfügen. Dadurch wird sichergestellt, dass alle anderen Seiten sicher sind. Sie müssen ValidateRequest="false"Ihre ASPX-Seite NICHT einfügen.

<configuration>
...
  <location path="MyFolder/.aspx">
    <system.web>
      <pages validateRequest="false" />
      <httpRuntime requestValidationMode="2.0" />
    </system.web>
  </location>
...
</configuration>

Es ist sicherer, dies in Ihrer web.config zu steuern, da Sie auf Site-Ebene sehen können, welche Seiten Markup als Eingabe zulassen.

Sie müssen die Eingabe auf Seiten, auf denen die Anforderungsüberprüfung deaktiviert ist, weiterhin programmgesteuert überprüfen.

Carter Medlin
quelle
Weitere Informationen zu requestValidationMode = 2 | 4 finden Sie hier: msdn.microsoft.com/en-us/library/…
GlennG
Leider funktioniert dies mit ASP.net 2.0 nicht so wie es ist. Entfernen Sie die httpRuntime-Zeile und es wird funktionieren.
Fandango68
Ich habe eine Warnung hinzugefügt, die die Leute daran erinnert, Eingaben manuell zu validieren, wenn die Validierung deaktiviert ist.
Carter Medlin
72

Die vorherigen Antworten sind großartig, aber niemand hat gesagt, wie ein einzelnes Feld von der Validierung für HTML / JavaScript-Injektionen ausgeschlossen werden kann. Ich weiß nichts über frühere Versionen, aber in MVC3 Beta können Sie dies tun:

[HttpPost, ValidateInput(true, Exclude = "YourFieldName")]
public virtual ActionResult Edit(int id, FormCollection collection)
{
    ...
}

Dadurch werden weiterhin alle Felder außer dem ausgeschlossenen überprüft. Das Schöne daran ist, dass Ihre Validierungsattribute das Feld immer noch validieren, Sie jedoch nicht die Ausnahmen "Ein potenziell gefährlicher Request.Form-Wert wurde vom Client erkannt" erhalten.

Ich habe dies zum Überprüfen eines regulären Ausdrucks verwendet. Ich habe mein eigenes ValidationAttribute erstellt, um festzustellen, ob der reguläre Ausdruck gültig ist oder nicht. Da reguläre Ausdrücke etwas enthalten können, das wie ein Skript aussieht, habe ich den obigen Code angewendet. Der reguläre Ausdruck wird noch geprüft, ob er gültig ist oder nicht, aber nicht, ob er Skripte oder HTML enthält.

Gligoran
quelle
10
Leider sieht es so aus, als ob die Ausschlussfunktion aus MVC 3 RTW entfernt wurde :(
Matt Greer
2
Es war auch nicht in MVC 4
wilsjd
9
Verwenden Sie [AllowHtml]die Eigenschaften des Modells anstelle [ValidateInput]der Aktion, um das gleiche Endergebnis zu erzielen.
Mrchief
2
@Christof Beachten Sie, dass meine Antwort 5 Jahre alt ist. Ich bin schon lange nicht mehr auf dieses Problem gestoßen, daher gibt es möglicherweise viel bessere Möglichkeiten, damit umzugehen. In Bezug auf diese beiden Optionen denke ich, dass es von Ihrer Situation abhängt. Vielleicht machen Sie dieses Modell in mehr als einer Aktion verfügbar und an einigen Stellen ist HTML erlaubt oder nicht. In einem solchen Fall [AllowHtml]ist keine Option. Ich empfehle, diesen Artikel zu lesen : weblogs.asp.net/imranbaloch/… , aber auch er ist etwas alt und möglicherweise veraltet.
Gligoran
1
Es gibt immer noch eine Möglichkeit, bestimmte Methodenparameter von der Validierung auszuschließen. Lesen Sie
Alex
51

In ASP.NET MVC müssen Sie requestValidationMode = "2.0" und validateRequest = "false" in web.config festlegen und ein ValidateInput-Attribut auf Ihre Controller-Aktion anwenden:

<httpRuntime requestValidationMode="2.0"/>

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

und

[Post, ValidateInput(false)]
public ActionResult Edit(string message) {
    ...
}
Ranthonissen
quelle
2
Für mich validateRequest="false"war das nicht nötig, nurrequestValidationMode="2.0"
Tom Redfern
requestValidationMode = "2.0" generiert weiterhin den Fehler mit HTML-codierten Daten. Keine Lösung außer base64 alles zu codieren und dann mitzusenden.
MC9000
48

Sie können Textfeldinhalte in HTML codieren , dies verhindert jedoch leider nicht, dass die Ausnahme auftritt. Nach meiner Erfahrung führt kein Weg daran vorbei, und Sie müssen die Seitenüberprüfung deaktivieren. Damit sagen Sie: "Ich werde vorsichtig sein, das verspreche ich."

Pavel Chuchuva
quelle
43

Ignorieren Sie bei MVC die Eingabevalidierung durch Hinzufügen

[ValidateInput (false)]

über jeder Aktion im Controller.

A.Dara
quelle
Dies scheint nicht zu funktionieren, wenn es über eine konfigurierte Route zur Controller-Methode gelangt.
PandaWood
Eigentlich ist die technische Erklärung ist , dass dies nur funktioniert , wenn die säumigen Zeichen in dem „Query - String“ ist ... wenn es im Anforderungspfad ist, Attribut - Validierung nicht Arbeit
PandaWood
42

Sie können diesen Fehler in Global.asax abfangen. Ich möchte noch validieren, zeige aber eine entsprechende Meldung. In dem unten aufgeführten Blog war ein Beispiel wie dieses verfügbar.

    void Application_Error(object sender, EventArgs e)
    {
        Exception ex = Server.GetLastError();

        if (ex is HttpRequestValidationException)
        {
            Response.Clear();
            Response.StatusCode = 200;
            Response.Write(@"[html]");
            Response.End();
        }
    }

Das Weiterleiten auf eine andere Seite scheint ebenfalls eine vernünftige Antwort auf die Ausnahme zu sein.

http://www.romsteady.net/blog/2007/06/how-to-catch-httprequestvalidationexcep.html

BenMaddox
quelle
40

Die Antwort auf diese Frage ist einfach:

var varname = Request.Unvalidated["parameter_name"];

Dies würde die Validierung für die bestimmte Anforderung deaktivieren.

Flakomalo
quelle
1
Gilt nur für ASP.NET 4.5 (und vermutlich für alles, was danach kommt). Pre 4.5 unterstützt dies nicht.
Beska
3
Ich wünschte, ich könnte auf diese Weise stoßen. Ich verwende .NET 4.5 und genau das habe ich benötigt, da ich MVC nicht verwende und die web.config nicht ändern kann.
Chris Gillum
1
Ja, aber was ist, wenn Sie .Net 2 verwenden? Einige von uns haben keine Wahl
Fandango68
das bekommt POST oder GET Parameter?
Max4ever
Wollen Sie damit sagen, dass dies eine Ausnahme verhindert, die bereits ausgelöst wurde? Oder verzögert .net 4.5 die Ausnahme und Validierung, bis tatsächlich Daten aus dem gelesen werden Request?
Ebyrob
34

Beachten Sie bitte, dass einige .NET-Steuerelemente die Ausgabe automatisch in HTML codieren. Wenn Sie beispielsweise die Eigenschaft .Text in einem TextBox-Steuerelement festlegen, wird sie automatisch codiert. Das bedeutet konkret, <in &lt;, >in &gt;und &in umzuwandeln &amp;. Seien Sie also vorsichtig, wenn Sie dies tun ...

myTextBox.Text = Server.HtmlEncode(myStringFromDatabase); // Pseudo code

Die .Text-Eigenschaft für HyperLink, Literal und Label codiert jedoch keine HTML-Code, sodass Server.HtmlEncode () umbrochen wird. Alles, was für diese Eigenschaften festgelegt wird, ist ein Muss, wenn Sie verhindern möchten, dass <script> window.location = "http://www.google.com"; </script>es auf Ihrer Seite ausgegeben und anschließend ausgeführt wird.

Experimentieren Sie ein wenig, um zu sehen, was codiert wird und was nicht.

Peter Mortensen
quelle
29

Fügen Sie in der Datei web.config innerhalb der Tags das httpRuntime-Element mit dem Attribut requestValidationMode = "2.0" ein. Fügen Sie außerdem das Attribut validateRequest = "false" in das Seitenelement ein.

Beispiel:

<configuration>
  <system.web>
   <httpRuntime requestValidationMode="2.0" />
  </system.web>
  <pages validateRequest="false">
  </pages>
</configuration>
Mahdi Jokar
quelle
1
Für mich war validateRequest = "false" nicht erforderlich, nur requestValidationMode = "2.0"
Tom Redfern
3
Der Abschnitt "Seiten" muss sich im Abschnitt "system.web" befinden.
Carter Medlin
noch einmal eine gefährliche Antwort.
MC9000
Ich brauchte beides. Vielen Dank
Jack
23

Wenn Sie ValidateRequest nicht deaktivieren möchten, müssen Sie eine JavaScript-Funktion implementieren, um die Ausnahme zu vermeiden. Es ist nicht die beste Option, aber es funktioniert.

function AlphanumericValidation(evt)
{
    var charCode = (evt.charCode) ? evt.charCode : ((evt.keyCode) ? evt.keyCode :
        ((evt.which) ? evt.which : 0));

    // User type Enter key
    if (charCode == 13)
    {
        // Do something, set controls focus or do anything
        return false;
    }

    // User can not type non alphanumeric characters
    if ( (charCode <  48)                     ||
         (charCode > 122)                     ||
         ((charCode > 57) && (charCode < 65)) ||
         ((charCode > 90) && (charCode < 97))
       )
    {
        // Show a message or do something
        return false;
    }
}

Fügen Sie dann im Code dahinter beim PageLoad-Ereignis das Attribut mit dem nächsten Code zu Ihrem Steuerelement hinzu:

Me.TextBox1.Attributes.Add("OnKeyPress", "return AlphanumericValidation(event);")
Peter Mortensen
quelle
4
Dadurch ist die App weiterhin anfällig für erfundene POST-Anforderungen. Ein normaler Benutzer hat Probleme bei der Eingabe von Zeichen wie: oder Anführungszeichen, aber ein normaler Hacker hat keine Probleme, fehlerhafte Daten auf dem Server zu veröffentlichen. Ich würde das abwarten.
Radu094
13
@ Radu094: Mit dieser Lösung können Sie ValidateRequest = true beibehalten, was bedeutet, dass Hacker immer noch an diese Wand stoßen. Stimmen Sie ab, da Sie dadurch weniger anfällig sind als das Deaktivieren von ValidateRequest.
jbehren
21

Es scheint, dass noch niemand das Folgende erwähnt hat, aber es behebt das Problem für mich. Und bevor jemand sagt, ja, es ist Visual Basic ... igitt.

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Example.aspx.vb" Inherits="Example.Example" **ValidateRequest="false"** %>

Ich weiß nicht, ob es irgendwelche Nachteile gibt, aber für mich hat das erstaunlich funktioniert.

Piercy
quelle
Funktioniert für Webformulare c # oder VB
TheAlbear
19

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;
    }
}
Sel
quelle
Nett! War sich der Möglichkeit nicht bewusst, den Anforderungsvalidator zu ersetzen. Anstatt wie Sie nur "ok" zu sagen, habe ich diese Idee dahingehend erweitert, dass Felder, deren Name auf "_NoValidation" endet, nicht überprüft werden. Code unten.
Walden Leverich
Walden Leverich, um dies zu tun, siehe [AllowHtml] Attribut
Sel
Sel, ja in einer MVC-Umgebung, die funktionieren würde. Aber in einer Webforms-Anwendung habe ich kein Modell, auf dem ich das machen kann. :-)
Walden Leverich
15

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

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

Wenn Sie Framework 4.5 verwenden, wird 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 nur eine einzelne Seite möchten, sollten Sie in Ihrer Aspx-Datei die erste Zeile wie folgt einfügen:

<%@ Page EnableEventValidation="false" %>

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

Ich empfehle es nicht zu tun.

Durgesh Pandey
quelle
13

In ASP.NET können Sie die Ausnahme abfangen und etwas dagegen tun, z. B. eine freundliche Nachricht anzeigen oder auf eine andere Seite umleiten. Außerdem besteht 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();
    }
}
Jaider
quelle
13

Ich denke, Sie könnten es in einem Modul tun; aber das lässt einige Fragen offen; Was ist, wenn Sie die Eingabe in einer Datenbank speichern möchten? Da Sie verschlüsselte Daten in der Datenbank speichern, vertrauen Sie plötzlich den Eingaben, was wahrscheinlich eine schlechte Idee ist. Idealerweise speichern Sie nicht codierte Rohdaten in der Datenbank und codieren sie jedes Mal.

Das Deaktivieren des Schutzes auf Seitenebene und das anschließende Codieren ist eine bessere Option.

Anstatt Server.HtmlEncode zu verwenden, sollten Sie sich die neuere, vollständigere Anti-XSS-Bibliothek des Microsoft ACE-Teams ansehen .

Blasrohrpfeil
quelle
12

Ursache

ASP.NET überprüft standardmäßig alle Eingabesteuerelemente auf potenziell unsichere Inhalte, die zu Cross-Site-Scripting (XSS) und SQL-Injektionen führen können . Daher wird ein solcher Inhalt durch Auslösen der obigen Ausnahme nicht zugelassen. Standardmäßig wird empfohlen, diese Überprüfung bei jedem Postback zuzulassen.

Lösung

In vielen Fällen müssen Sie HTML-Inhalte über Rich TextBoxes oder Rich Text Editors an Ihre Seite senden. In diesem Fall können Sie diese Ausnahme vermeiden, indem Sie das ValidateRequest-Tag in der @PageDirektive auf false setzen.

<%@ Page Language="C#" AutoEventWireup="true" ValidateRequest = "false" %>

Dadurch wird die Validierung von Anforderungen für die Seite deaktiviert, für die Sie das ValidateRequest-Flag auf false gesetzt haben. Wenn Sie dies deaktivieren möchten, überprüfen Sie dies in Ihrer gesamten Webanwendung. Sie müssen es in Ihrem Abschnitt web.config <system.web> auf false setzen

<pages validateRequest ="false" />

Für .NET 4.0 oder höhere Frameworks müssen Sie außerdem die folgende Zeile im Abschnitt <system.web> hinzufügen, damit die oben genannten Funktionen ausgeführt werden.

<httpRuntime requestValidationMode = "2.0" />

Das ist es. Ich hoffe, dies hilft Ihnen dabei, das oben genannte Problem zu beseitigen.

Referenz von: ASP.Net Fehler: Ein möglicherweise gefährlicher Request.Form-Wert wurde vom Client erkannt

vakeel
quelle
10

Ich habe eine Lösung gefunden, die JavaScript zum Codieren der Daten verwendet, die in .NET dekodiert ist (und keine jQuery erfordert).

  • Machen Sie das Textfeld zu einem HTML-Element (wie Textbereich) anstelle eines ASP-Elements.
  • Fügen Sie ein verstecktes Feld hinzu.
  • Fügen Sie Ihrem Header die folgende JavaScript-Funktion hinzu.

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

Fügen Sie in Ihren Textbereich eine Änderung ein, die boo () aufruft:

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

Verwenden Sie schließlich in .NET

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

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

Hier ist ein Beispiel, das ich (MC9000) über jQuery entwickelt habe:

$(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 das Markup:

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

Das funktioniert super. Wenn ein Hacker versucht, über die Umgehung von JavaScript zu posten, wird nur der Fehler angezeigt. Sie können alle diese in einer Datenbank verschlüsselten Daten auch speichern, sie dann (auf der Serverseite) entfernen und analysieren und nach Angriffen suchen, bevor Sie sie an anderer Stelle anzeigen.

Jason Shuler
quelle
Dies ist eine gute Lösung. Es ist eine richtige manuelle Methode, um es selbst zu kontrollieren und nicht die gesamte Website oder Seite ungültig zu machen
Fandango68
Stellen Sie sicher, dass Sie ein HTML-Markup verwenden, kein ASP.Net-Steuerelement (dh kein runat = "Server") für den Textbereich, und verwenden Sie dann das versteckte ASP.Net-Steuerelement für das versteckte. Dies ist die beste Lösung, die ich gesehen habe, ohne irgendetwas zu kompromittieren. Natürlich möchten Sie Ihre Daten für XSS, SQL Injection auf der Serverseite analysieren, aber zumindest können Sie HTML
MC9000
escape(...)kann lange dauern. In meinem Fall war das Markup eine vollständige (2 MB) XML-Datei. Sie könnten fragen: "Warum verwenden Sie nicht einfach <input type="file"...und ... ich stimme Ihnen zu :)
Die rote Erbse
10

Die anderen Lösungen hier sind nett, aber es ist ein bisschen schmerzhaft, [AllowHtml] auf jede einzelne Modelleigenschaft anwenden zu müssen, insbesondere wenn Sie über 100 Modelle auf einer Site mit angemessener Größe haben.

Wenn Sie wie ich diese (meiner Meinung nach ziemlich sinnlose) Funktion außerhalb der Site deaktivieren möchten, können Sie die Execute () -Methode in Ihrem Basis-Controller überschreiben (wenn Sie noch keinen Basis-Controller haben, können Sie einen erstellen ziemlich nützlich für die Anwendung allgemeiner Funktionen).

    protected override void Execute(RequestContext requestContext)
    {
        // Disable requestion validation (security) across the whole site
        ValidateRequest = false;
        base.Execute(requestContext);
    }

Stellen Sie einfach sicher, dass Sie alles HTML-codieren, was in die Ansichten gepumpt wird, die aus Benutzereingaben stammen (dies ist ohnehin das Standardverhalten in ASP.NET MVC 3 mit Razor, es sei denn, Sie verwenden aus irgendeinem bizarren Grund Html.Raw () sollte diese Funktion nicht erfordern.

magritte
quelle
9

Ich habe auch diesen Fehler bekommen.

In meinem Fall hat ein Benutzer ein Akzentzeichen áin einen Rollennamen eingegeben (in Bezug auf den ASP.NET-Mitgliedschaftsanbieter).

Ich übergebe den Rollennamen an eine Methode, um Benutzern diese Rolle zu gewähren, und die $.ajaxPost-Anfrage ist kläglich fehlgeschlagen ...

Ich habe dies getan, um das Problem zu lösen:

Anstatt

data: { roleName: '@Model.RoleName', users: users }

Mach das

data: { roleName: '@Html.Raw(@Model.RoleName)', users: users }

@Html.Raw hat den Trick gemacht.

Ich habe den Rollennamen als HTML-Wert erhalten roleName="Cadastro b&#225;s". Dieser Wert mit HTML-Entität &#225;wurde von ASP.NET MVC blockiert. Jetzt erhalte ich den roleNameParameterwert so, wie er sein sollte: roleName="Cadastro Básico"und die ASP.NET MVC-Engine blockiert die Anforderung nicht mehr.

Leniel Maccaferri
quelle
9

Deaktivieren Sie die Seite Validierung , wenn Sie wirklich die Sonderzeichen benötigen mögen, >,,< usw. dann sicher , dass , wenn die Benutzereingabe angezeigt wird, die Daten HTML-codiert.

Bei der Seitenüberprüfung liegt eine Sicherheitslücke vor, sodass diese umgangen werden kann. Auch auf die Seitenüberprüfung sollte nicht allein vertraut werden.

Siehe: http://web.archive.org/web/20080913071637/http://www.procheckup.com:80/PDFs/bypassing-dot-NET-ValidateRequest.pdf

woany
quelle
Die Verbindung ist unterbrochen.
Peter Mortensen
7

Sie können auch die Escape- Funktion (Zeichenfolge) von JavaScript verwenden , um die Sonderzeichen zu ersetzen. Verwenden Sie dann serverseitig Server. URLDecode (Zeichenfolge) zum Zurückschalten.

Auf diese Weise müssen Sie die Eingabevalidierung nicht deaktivieren, und anderen Programmierern wird klarer, dass die Zeichenfolge möglicherweise HTML-Inhalt enthält.

Trisped
quelle
7

Ich habe vor jedem Postback JavaScript verwendet, um nach den Zeichen zu suchen, die Sie nicht wollten, wie zum Beispiel:

<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 hauptsächlich aus Dateneingaben, und es gibt nur sehr wenige Elemente, die Postbacks durchführen, aber zumindest ihre Daten bleiben erhalten.

Ryan
quelle
Es sollten große Klammern anstelle kleiner Klammern stehen. Wie `if (tbs [i] .type == 'text') {` anstelle von `if (tbs (i) .type == 'text') {`
Shilpa Soni
5

Sie können etwas verwenden wie:

var nvc = Request.Unvalidated().Form;

Sollte später nvc["yourKey"]funktionieren.

Ady Levy
quelle
Vielen Dank, Ihre Antwort hat mir viel Zeit
gespart
4

Solange es sich nur um "<" und ">" (und nicht um das doppelte Anführungszeichen selbst) handelt und Sie sie in einem Kontext wie <input value = " this " /> verwenden, sind Sie sicher (während für <textarea) > dieses </ textarea> wären Sie natürlich verwundbar). Das mag Ihre Situation vereinfachen, aber für alles andere verwenden Sie eine der anderen veröffentlichten Lösungen.

Paweł Hajdan
quelle
4

Wenn Sie Ihren Benutzern nur mitteilen möchten, dass <und> nicht verwendet werden soll, ABER Sie möchten nicht, dass das gesamte Formular zuvor verarbeitet / zurückgeschickt wird (und alle Eingaben verloren gehen), können Sie nicht einfach ein Formular eingeben Validator im Feld, um nach diesen (und möglicherweise anderen potenziell gefährlichen) Zeichen zu suchen?

Kapitän Kröte
quelle
Post sagte "Validator" bitte
mxmissile
4

Keiner der Vorschläge hat bei mir funktioniert. Ich wollte diese Funktion sowieso nicht für die gesamte Website deaktivieren, da ich zu 99% nicht möchte, dass meine Benutzer HTML in Webformulare einfügen. Ich habe gerade meine eigene Umgehungsmethode erstellt, da ich der einzige bin, der diese spezielle Anwendung verwendet. Ich konvertiere die Eingabe im Code dahinter in HTML und füge sie in meine Datenbank ein.

Mike S.
quelle