it-swarm-eu.dev

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

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

Ich möchte nicht in die Diskussion einsteigen, wie klug es ist, eine Ausnahme auszulösen oder eine gesamte Webanwendung zum Absturz zu bringen, weil jemand einen Buchstaben in ein Textfeld eingegeben hat.

Die Ausnahme wird eingefangen und angezeigt

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

scheint mir nicht professionell genug zu sein.

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

Idealerweise: Wenn ein Beitrag zurück erscheint, der HTML-geschützte Zeichen enthält, wird der in der Formularauflistung veröffentlichte Wert automatisch HTML-codiert .. __ Die .Text-Eigenschaft meines Textfelds ist something & lt; html & gt;

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

1379
Radu094

Ich denke, Sie greifen aus dem falschen Blickwinkel an, indem Sie versuchen, alle veröffentlichten Daten zu kodieren.

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

Außerdem ist "<" nicht grundsätzlich 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 verschiedene 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 dagegen ist gefährlich, wenn Zeichenfolgen in SQL-Abfragen interpoliert werden. Es ist jedoch absolut sicher, wenn es sich um einen Teil eines Namens handelt, der aus einem Formular gesendet oder aus einem Datenbankfeld gelesen wird.

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

Wenn Sie sicher sind, dass Sie überall HTML-kodieren, wenn Sie Zeichenfolgen an HTML übergeben, setzen Sie validateRequest="false" in der <%@ Page ... %>-Direktive in Ihren .aspx-Dateien.

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

1028
JacquesB

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
497
Zack Peterson

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

Dadurch kann eine Anforderung das HTML-Markup während der Modellbindung einschließen, indem die Anforderungsüberprüfung für die Eigenschaft übersprungen wird.

[AllowHtml]
public string Description { get; set; }
384

Wenn Sie mit .NET 4.0 arbeiten, fügen Sie dies in Ihre web.config -Datei in den <system.web>-Tags ein:

<httpRuntime requestValidationMode="2.0" />

In .NET 2.0 wird die Anforderungsüberprüfung nur auf aspx-Anforderungen angewendet. In .NET 4.0 wurde dies um alle -Anfragen erweitert. Sie können bei der Verarbeitung von .aspx auf only zurücksetzen, indem Sie die XSS-Überprüfung durchführen, indem Sie Folgendes angeben:

requestValidationMode="2.0"

Sie können die Anforderungsüberprüfung vollständig deaktivieren, indem Sie Folgendes angeben:

validateRequest="false"
206
JordanC

Bei ASP.NET 4.0 können Sie Markup 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 NICHT ValidateRequest="false" in Ihre ASPX-Seite 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 die Markierung als Eingabe zulassen.

Sie müssen noch immer programmgesteuert Eingaben auf Seiten überprüfen, auf denen die Anforderungsüberprüfung deaktiviert ist.

108
Carter Medlin

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 kenne keine früheren Versionen, aber in MVC3 Beta können Sie Folgendes tun:

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

Dadurch werden alle Felder außer dem ausgeschlossenen Feld noch gültig. Das Schöne daran ist, dass Ihre Validierungsattribute das Feld zwar immer noch validieren, aber Sie erhalten einfach nicht die Ausnahmen "Ein möglicherweise gefährlicher Request.Form-Wert wurde vom Client erkannt".

Ich habe dies zur Validierung eines regulären Ausdrucks verwendet. Ich habe mein eigenes ValidationAttribute erstellt, um zu sehen, 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, nicht jedoch, wenn er Skripts oder HTML enthält.

70
gligoran

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) {
    ...
}
48
ranthonissen

Sie können HTML encodieren Textfeldinhalt, aber das stoppt leider nicht die Ausnahme. Nach meiner Erfahrung führt kein Weg vorbei, und Sie müssen die Seitenvalidierung deaktivieren. Damit sagen Sie: "Ich werde vorsichtig sein, das verspreche ich."

45
Pavel Chuchuva

Ignorieren Sie bei MVC die Eingabeüberprüfung durch Hinzufügen 

[ValidateInput (false)]

über jeder Aktion im Controller.

42
A.Dara

Sie können diesen Fehler in Global.asax abfangen. Ich möchte noch bestätigen, aber eine entsprechende Nachricht anzeigen. In dem unten aufgelisteten Blog war eine solche Probe 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 Umleiten auf eine andere Seite scheint auch eine sinnvolle Antwort auf die Ausnahme zu sein.

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

41
BenMaddox

Bitte beachten Sie, dass einige .NET-Steuerelemente die Ausgabe automatisch mit HTML kodieren. Wenn Sie beispielsweise die .Text-Eigenschaft für ein TextBox-Steuerelement festlegen, wird diese automatisch codiert. Dies bedeutet insbesondere die Umwandlung von < in &lt;, > in &gt; und & in &amp;. Seien Sie also vorsichtig, dies zu tun ...

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

Die .Text-Eigenschaft für HyperLink, Literal und Label wird jedoch keine HTML-Codierung durchführen. Server.HtmlEncode (); Um diese Eigenschaften festzulegen, müssen Sie festlegen, dass <script> window.location = "http://www.google.com"; </script> nicht auf Ihrer Seite ausgegeben und anschließend ausgeführt werden soll.

Machen Sie ein wenig experimentieren, um zu sehen, was verschlüsselt wird und was nicht.

33

Die Antwort auf diese Frage ist einfach:

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

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

31
flakomalo

Fügen Sie in die Datei web.config innerhalb der Tags das httpRuntime-Element mit dem Attribut requestValidationMode = "2.0" ein. Fügen Sie auch das Attribut validateRequest = "false" im Element pages hinzu.

Beispiel:

<configuration>
  <system.web>
   <httpRuntime requestValidationMode="2.0" />
  </system.web>
  <pages validateRequest="false">
  </pages>
</configuration>
27
Mahdi jokar

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 hinter dem PageLoad-Ereignis das Attribut mit dem nächsten Code zu Ihrem Steuerelement hinzu:

Me.TextBox1.Attributes.Add("OnKeyPress", "return AlphanumericValidation(event);")
23
YORENGOY

Es scheint, dass noch niemand das Folgende erwähnt hat, aber es behebt das Problem für mich. Und bevor irgendjemand sagt, es sei Visual Basic ... yuck.

<%@ 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 funktionierte das erstaunlich.

20
Piercy

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;
    }
}
17
Sel

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

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

Wenn Sie das 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 einzige Seite haben möchten, sollten Sie in Ihre Aspx-Datei die erste Zeile wie folgt einfügen:

<%@ Page EnableEventValidation="false" %>

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

Ich empfehle es nicht zu machen.

14
Durgesh Pandey

In ASP.NET können Sie die Ausnahme abfangen und etwas dagegen unternehmen, z. B. Anzeigen einer freundlichen Nachricht oder Weiterleiten auf eine andere Seite ... 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();
    }
}
13
Jaider

Ich denke, du könntest es in einem Modul tun. aber das lässt einige Fragen offen; Was ist, wenn Sie die Eingabe in einer Datenbank speichern möchten? Plötzlich, weil Sie verschlüsselte Daten in der Datenbank speichern, vertrauen Sie auf die Eingaben, was wahrscheinlich eine schlechte Idee ist. Idealerweise speichern Sie rohe, unverschlüsselte Daten in der Datenbank und die Verschlüsselung jedes Mal.

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

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

12
blowdart

Die anderen Lösungen hier sind Nizza, aber es ist ein bisschen königlicher Schmerz im Hintergrund, [AllowHtml] auf jede einzelne Model-Eigenschaft anwenden zu müssen, insbesondere wenn Sie über 100 Modelle auf einer anständigen Größe haben.

Wenn Sie, wie ich, diese (IMHO ziemlich sinnlose) Funktion außerhalb der Site deaktivieren möchten, können Sie die Execute () -Methode in Ihrem Basiscontroller überschreiben (wenn Sie nicht bereits über einen Basiscontroller verfügen, empfehle ich Ihnen, einen zu 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 nur sicher, dass Sie alles HTML-kodieren, das in die Ansichten gepumpt wird, die von den Benutzereingaben stammen (das Standardverhalten in ASP.NET MVC 3 mit Razor ist jedoch sowieso, sofern Sie aus irgendeinem bizarren Grund Html.Raw () verwenden) sollte diese Funktion nicht erfordern.

10
magritte

Deaktivieren Sie die Seitenüberprüfung, wenn Sie die Sonderzeichen wie >, < usw. wirklich benötigen. Stellen Sie dann sicher, dass die Daten bei der Anzeige der Benutzereingabe HTML-kodiert sind. 

Bei der Seitenvalidierung liegt eine Sicherheitsanfälligkeit vor, sodass diese umgangen werden kann. Auch auf die Seitenvalidierung sollte nicht ausschließlich zurückgegriffen werden.

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

9
woany

Ursache

ASP.NET überprüft standardmäßig alle Eingabesteuerelemente auf möglicherweise unsichere Inhalte, die zu Cross-Site-Scripting (XSS) - und SQL-Injektionen führen können. Daher verbietet es diesen Inhalt, indem es die obige Ausnahme auslöst. Standardmäßig wird empfohlen, diese Überprüfung für jedes 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 @Page-Direktive auf false setzen.

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

Dadurch wird die Überprüfung 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 die gesamte Webanwendung. Sie müssen es in Ihrem Abschnitt web.config <system.web> auf false setzen

<pages validateRequest ="false" />

Für .NET 4.0-Frameworks oder höher müssen Sie außerdem die folgende Zeile im Abschnitt <system.web> hinzufügen, damit die oben genannten Aufgaben erfüllt werden.

<httpRuntime requestValidationMode = "2.0" />

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

Referenz durch: ASP.Net Fehler: Ein potenziell gefährlicher Request.Form-Wert wurde vom Client erkannt

9
vakeel

Ich habe eine Lösung gefunden, die zur Kodierung der Daten JavaScript verwendet, das in .NET dekodiert wird (und jQuery nicht erforderlich ist).

  • Machen Sie das Textfeld zu einem HTML-Element (wie ein Textfeld) 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 Ihrem Textbereich ein onchange ein, das boo () aufruft:

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

Schließlich in .NET verwenden

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. Dies bietet jedoch eine Lösung, wenn Sie die web.config nicht bearbeiten können

Hier ist ein Beispiel, das ich (MC9000) mit jQuery entworfen und verwendet 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 das Umgehen von JavaScript zu posten, wird ihm nur der Fehler angezeigt. Sie können alle diese in einer Datenbank verschlüsselten Daten auch speichern, sie dann auf der Serverseite deaktivieren und auf Angriffe analysieren und prüfen, bevor sie an anderer Stelle angezeigt werden.

9
Jason Shuler

Ich habe auch diesen Fehler erhalten.

In meinem Fall hat ein Benutzer ein Akzentzeichen á in einen Rollennamen (bezüglich des ASP.NET-Mitgliedschaftsanbieters) eingegeben.

Ich übergebe den Rollennamen an eine Methode, um Benutzern diese Rolle zu erteilen, und die $.ajax-Post-Anforderung schlug fehl ...

Ich habe das 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 erhielt den Rollennamen als HTML-Wert roleName="Cadastro b&#225;s". Dieser Wert mit der HTML-Entität &#225; wurde von ASP.NET MVC blockiert. Jetzt erhalte ich den Parameterwert roleName so, wie er sein sollte: roleName="Cadastro Básico" und die ASP.NET MVC-Engine blockiert die Anforderung nicht mehr.

9

Sie können auch die JavaScript-Funktion escape (string) verwenden, um die Sonderzeichen zu ersetzen. Server-seitig verwenden Sie Server. URLDecode (string) , um es zurückzuschalten.

Auf diese Weise müssen Sie die Überprüfung der Eingabe nicht deaktivieren und anderen Programmierern wird klarer, dass der String möglicherweise HTML-Inhalt enthält.

7
Trisped

Am Ende habe ich JavaScript vor jedem Postback 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 sehr wenige Elemente, die Postbacks ausführen, aber zumindest werden ihre Daten beibehalten.

6
Ryan

Solange dies nur} _ "<" und ">" (und nicht das doppelte Anführungszeichen selbst) sind, verwenden Sie sie im Kontext wie <input value = "this" /> , Sie sind sicher (während für <textarea> this </ textarea> Sie natürlich anfällig sind). Das kann Ihre Situation vereinfachen, aber für irgendetwas eine andere Lösung verwenden.

4
Paweł Hajdan

Wenn Sie Ihren Benutzern lediglich mitteilen möchten, dass <und> NICHT verwendet werden sollen, ABER Sie möchten nicht, dass das gesamte Formular zurückverarbeitet/gepostet wird (und alle Eingaben verloren gehen) Validator um das Feld, um nach diesen (und möglicherweise anderen potenziell gefährlichen) Zeichen zu suchen?

4
Captain Toad

Sie können so etwas verwenden:

var nvc = Request.Unvalidated().Form;

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

4
Ady Levy

Keiner der Vorschläge funktionierte für mich. Ich wollte diese Funktion sowieso nicht für die gesamte Website deaktivieren, da ich zu 99% nicht will, dass meine Benutzer HTML-Formulare in Webformulare einfügen. Ich habe gerade meine eigene Arbeitsweise erstellt, da ich der einzige bin, der diese spezielle Anwendung verwendet. Ich konvertiere die Eingabe in HTML im Code dahinter und füge sie in meine Datenbank ein.

4
Mike S.

Sie können das HTML-Codierungsfeld automatisch in der benutzerdefinierten Model Binder-Datei einfügen. Meine Lösung etwas anders, ich habe Fehler in ModelState und Fehlermeldung in der Nähe des Feldes. Es ist einfach, diesen Code für die automatische Codierung 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 Application_Start:

ModelBinders.Binders.DefaultBinder = new AppModelBinder();

Beachten Sie, dass es nur für Formularfelder funktioniert. Gefährlicher Wert, der nicht an das Steuerungsmodell übergeben wird, sondern in ModelState gespeichert wird und im Formular mit Fehlermeldung erneut angezeigt wird. 

Gefährliche Zeichen in URL können folgendermaßen 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();
   }
}   
3
Sel

Sie sollten die Server.HtmlEncode-Methode verwenden, um Ihre Site vor gefährlichen Eingaben zu schützen.

Mehr Infos hier

3
bastos.sergio

Wie in meinem Kommentar zu Sels Antwort angegeben, ist dies unsere Erweiterung eines benutzerdefinierten Anforderungsprüfers.

public class SkippableRequestValidator : RequestValidator
{
    protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
    {
        if (collectionKey != null && collectionKey.EndsWith("_NoValidation"))
        {
            validationFailureIndex = 0;
            return true;
        }

        return base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);
    }
}
2
Walden Leverich

Für diejenigen, die keine Modellbindung verwenden, die jeden Parameter aus der Request.Form extrahieren und sicher sind, dass der eingegebene Text keinen Schaden verursacht, gibt es einen anderen Weg. Keine großartige Lösung, aber es wird die Arbeit machen. 

Verschlüsseln Sie es vom Client aus als uri und senden Sie es dann.
z.B: 

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

Akzeptieren Sie es auf der Serverseite und dekodieren Sie es als URI.
z.B: 

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

oder 

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

bitte beachten Sie die Unterschiede zwischen UrlDecode und UnescapeDataString

2
Wahid Masud

Beachten Sie bitte auch, dass ASP.NET-Datenbindungssteuerelemente während der Datenbindung automatisch encode values ​​steuern. Dadurch wird das Standardverhalten aller ASP.NET-Steuerelemente (TextBox, Label usw.) geändert, die in der Variable ItemTemplate enthalten sind. Das folgende Beispiel demonstriert (ValidateRequest ist auf false gesetzt):

aspx

<%@ Page Language="C#" ValidateRequest="false" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication17._Default" %> <html> <body>
    <form runat="server">
        <asp:FormView ID="FormView1" runat="server" ItemType="WebApplication17.S" SelectMethod="FormView1_GetItem">
            <ItemTemplate>
                <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
                <asp:Label ID="Label1" runat="server" Text="<%#: Item.Text %>"></asp:Label>
                <asp:TextBox ID="TextBox2" runat="server" Text="<%#: Item.Text %>"></asp:TextBox>
            </ItemTemplate>
        </asp:FormView>
    </form> 

Code hinter

public partial class _Default : Page
{
    S s = new S();

    protected void Button1_Click(object sender, EventArgs e)
    {
        s.Text = ((TextBox)FormView1.FindControl("TextBox1")).Text;
        FormView1.DataBind();
    }

    public S FormView1_GetItem(int? id)
    {
        return s;
    }
}

public class S
{
    public string Text { get; set; }
}
  1. Wert des Falles: &#39;

Label1.Text wert: &#39;

TextBox2.Text wert: &amp;#39;

  1. Wert des Falles: <script>alert('attack!');</script>

Label1.Text wert: <script>alert('attack!');</script>

TextBox2.Text wert: &lt;script&gt;alert(&#39;attack!&#39;);&lt;/script&gt;

1
dpant

Eine Lösung

Ich möchte die Nachvalidierung nicht ausschalten (validateRequest = "false"). Andererseits ist es nicht akzeptabel, dass die Anwendung abstürzt, nur weil ein unschuldiger Benutzer <x Oder etwas eingibt.

Aus diesem Grund habe ich eine clientseitige Javascript-Funktion (xssCheckValidates) geschrieben, die eine vorläufige Überprüfung durchführt. Diese Funktion wird aufgerufen, wenn versucht wird, die Formulardaten wie folgt zu veröffentlichen:

<form id="form1" runat="server" onsubmit="return xssCheckValidates();">

Die Funktion ist recht einfach und könnte verbessert werden, aber sie macht ihre Arbeit.

Bitte beachten Sie, dass dies nicht dazu dient, das System vor Hacking zu schützen, sondern die Benutzer vor einer schlechten Erfahrung zu schützen. Die auf dem Server durchgeführte Anforderungsüberprüfung ist weiterhin aktiviert, und dies ist (sofern dies möglich ist) Teil des Schutzes des Systems.

Der Grund, warum ich hier "Teil von" sage, ist, dass ich gehört habe, dass die eingebaute Anforderungsvalidierung möglicherweise nicht ausreicht, sodass möglicherweise andere ergänzende Mittel erforderlich sind, um einen vollständigen Schutz zu gewährleisten. Aber auch hier hat die JavaScript-Funktion, die ich hier präsentiere, nichts mit dem Schutz des Systems zu tun. Es ist nur gedacht, um sicherzustellen, dass die Benutzer keine schlechten Erfahrungen machen.

Sie können es hier ausprobieren:

    function xssCheckValidates() {
      var valid = true;
      var inp = document.querySelectorAll(
          "input:not(:disabled):not([readonly]):not([type=hidden])" +
          ",textarea:not(:disabled):not([readonly])");
      for (var i = 0; i < inp.length; i++) {
        if (!inp[i].readOnly) {
          if (inp[i].value.indexOf('<') > -1) {
            valid = false;
            break;
          }
          if (inp[i].value.indexOf('&#') > -1) {
            valid = false;
            break;
          }
        }
      }
      if (valid) {
        return true;
      } else {
        alert('In one or more of the text fields, you have typed\r\nthe character "<" or the character sequence "&#".\r\n\r\nThis is unfortunately not allowed since\r\nit can be used in hacking attempts.\r\n\r\nPlease edit the field and try again.');
        return false;
      }
    }
<form onsubmit="return xssCheckValidates();" >
  Try to type < or &# <br/>
  <input type="text" /><br/>
  <textarea></textarea>
  <input type="submit" value="Send" />
</form>
1
Magnus

Für diejenigen, die noch immer auf Webformularen stecken, habe ich die folgende Lösung gefunden, mit der Sie die Validierung nur in einem Feld deaktivieren können! (Ich würde es hassen, es für die gesamte Seite zu deaktivieren.)

VB.NET:

Public Class UnvalidatedTextBox
    Inherits TextBox
    Protected Overrides Function LoadPostData(postDataKey As String, postCollection As NameValueCollection) As Boolean
        Return MyBase.LoadPostData(postDataKey, System.Web.HttpContext.Current.Request.Unvalidated.Form)
    End Function
End Class

C #:

public class UnvalidatedTextBox : TextBox
{
    protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
    {
        return base.LoadPostData(postDataKey, System.Web.HttpContext.Current.Request.Unvalidated.Form);
    }
}

Verwenden Sie jetzt einfach <prefix:UnvalidatedTextBox id="test" runat="server" /> anstelle von <asp:TextBox, und es sollte alle Zeichen zulassen (dies ist ideal für Kennwortfelder!)

1
Peter

Ich weiß, dass es sich bei dieser Frage um das Ausfüllen von Formularen handelt, aber ich möchte einige Details für Personen hinzufügen, die diesen Fehler unter Umständen anderer Personen erhalten haben. Es kann auch bei einem Handler auftreten, der zum Implementieren eines Web-Services verwendet wird. 

Angenommen, Ihr Webclient sendet POST - oder PUT-Anforderungen mit ajax und sendet entweder Json- oder XML-Text oder Rohdaten (einen Dateiinhalt) an Ihren Webdienst. Da Ihr Webdienst keine Informationen aus einem Content-Type-Header abrufen muss, hat Ihr JavaScript-Code diesen Header nicht auf Ihre Ajax-Anforderung festgelegt. Wenn Sie diesen Header jedoch nicht in einer POST/PUT-Ajax-Anforderung festlegen, kann Safari diesen Header hinzufügen: "Content-Type: application/x-www-form-urlencoded". Ich habe das auf Safari 6 auf dem iPhone beobachtet, aber andere Safari-Versionen/-Betriebssysteme oder Chrome können dasselbe tun. Beim Empfang dieses Content-Type-Headers gehen einige Teile von .NET Framework davon aus, dass die Anforderungshauptdatenstruktur einer HTML-Formularveröffentlichung entspricht, während es nicht zu einer HttpRequestValidationException-Ausnahme kam. Als erstes müssen Sie den Content-Type-Header natürlich immer auf einen anderen Formulartyp als einen MIME-Typ in einer POST/PUT-Ajax-Anforderung setzen, auch wenn dies für Ihren Web-Service unbrauchbar ist.

Ich habe auch dieses Detail entdeckt:
Unter diesen Umständen wird die Ausnahme "HttpRequestValidationException" ausgelöst, wenn Ihr Code versucht, auf die Sammlung "HttpRequest.Params" zuzugreifen. Überraschenderweise wird diese Ausnahme jedoch nicht erhöht, wenn auf die HttpRequest.ServerVariables-Auflistung zugegriffen wird. Dies zeigt, dass, während diese beiden Sammlungen nahezu identisch zu sein scheinen, eine auf die Anforderungsdaten durch Sicherheitsüberprüfungen zugreift und die andere nicht.

1
figolu

Setzen Sie in .NET 4.0 und höher, was der übliche Fall ist, folgende Einstellung in system.web

<system.web>
     <httpRuntime requestValidationMode="2.0" />
1
Kiran Chaudhari

verwenden Sie in meinem Fall asp: Textbox-Steuerelement (Asp.net 4.5), anstatt die All-Seite für validateRequest="false" festzulegen 

<asp:TextBox runat="server" ID="mainTextBox"
            ValidateRequestMode="Disabled"
 ></asp:TextBox>

im Textfeld, das die Ausnahme verursacht hat.

0
maozx

Verwenden Sie die Server.HtmlEncode("yourtext");

0
Voigt

Ich sehe, es wurde viel darüber geschrieben ... und ich habe nicht erwähnt, dass dies erwähnt wird ..__ Das ist seit .NET Framework 4.5 verfügbar

Die Einstellung ValidateRequestMode für ein Steuerelement ist eine großartige Option ..__ Auf diese Weise sind die anderen Steuerelemente auf der Seite weiterhin geschützt. Keine Änderungen an web.config erforderlich.

 protected void Page_Load(object sender, EventArgs e)
    {
             txtMachKey.ValidateRequestMode = ValidateRequestMode.Disabled;
    }
0
Chris Catignani