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

3voto

Magnus Punkte 1318

Eine Lösung

Ich möchte die Postvalidierung nicht abschalten (validateRequest="false"). Andererseits ist es nicht akzeptabel, dass die Anwendung abstürzt, nur weil ein unschuldiger Benutzer zufällig <x oder so ähnlich.

Deshalb habe ich eine clientseitige Javascript-Funktion (xssCheckValidates) geschrieben, die eine vorläufige Prüfung vornimmt. Diese Funktion wird aufgerufen, wenn versucht wird, die Formulardaten zu posten, etwa so:

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

Die Funktion ist recht einfach und könnte verbessert werden, aber sie erfüllt ihren Zweck.

Bitte beachten Sie, dass dies nicht dazu dient, das System vor Hackerangriffen zu schützen, sondern um die Benutzer vor schlechten Erfahrungen zu bewahren. Die Validierung von Anfragen auf dem Server ist nach wie vor aktiviert, und das ist (ein Teil) des Schutzes des Systems (in dem Maße, wie es dazu in der Lage ist).

Der Grund, warum ich hier "teilweise" sage, ist, dass ich gehört habe, dass die eingebaute Anforderungsvalidierung möglicherweise nicht ausreicht, so dass andere ergänzende Mittel notwendig sein könnten, um einen vollständigen Schutz zu haben. Aber noch einmal, die Javascript-Funktion, die ich hier vorstelle, hat nichts mit dem Schutz des Systems zu tun. Es ist sólo die sicherstellen sollen, dass die Nutzer 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>

0 Stimmen

Sie sollten davon ausgehen, dass jeder Code, der auf dem Client läuft, unterwandert wird.

2 Stimmen

@user169771, lesen Sie meine Antwort noch einmal, insbesondere den Teil, der mit "Bitte beachten Sie, dass dies nicht dazu dient, das System vor Hackerangriffen zu schützen..." beginnt.

2voto

Chris Catignani Punkte 4512

Wie ich sehe, wurde schon viel darüber geschrieben... und ich habe nicht gesehen, dass dies erwähnt wurde. Dies ist seit .NET Framework 4.5 verfügbar

Die ValidateRequestMode Einstellung für eine Kontrolle ist eine gute Option. Auf diese Weise sind die anderen Steuerelemente auf der Seite weiterhin geschützt. Keine Änderungen in der web.config erforderlich.

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

1 Stimmen

@PruTahan....und Sie mussten sich zu jedem Beitrag äußern, weil? Für die OP-Fehlermeldung gibt es eine ganze Reihe von Gründen.

2voto

figolu Punkte 1168

Ich weiß, dass es in dieser Frage um das Einstellen von Formularen geht, aber ich möchte gerne einige Details für diejenigen hinzufügen, die diesen Fehler unter anderen Umständen erhalten haben. Er könnte auch bei einem Handler auftreten, der zur Implementierung eines Webdienstes verwendet wird.

Angenommen, Ihr Web-Client sendet POST- oder PUT-Anfragen 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-Anfrage gesetzt. Wenn Sie diesen Header jedoch bei einer POST/PUT-Ajax-Anforderung nicht setzen, kann Safari diesen Header hinzufügen: "Content-Type: application/x-www-form-urlencoded". Ich habe das bei Safari 6 auf dem iPhone beobachtet, aber andere Safari-Versionen/OS oder Chrome können das auch tun. Wenn dieser Content-Type-Header empfangen wird, geht ein Teil von .NET Framework davon aus, dass die Datenstruktur des Anforderungskörpers einer HTML-Formularbuchung entspricht, während dies nicht der Fall ist, und löst eine HttpRequestValidationException-Ausnahme aus. Das erste, was zu tun ist, ist natürlich immer Content-Type Header auf etwas anderes als ein Formular MIME-Typ auf einem POST/PUT Ajax-Anfrage, auch wenn es nutzlos ist, um Ihre Web-Service.

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 ausgelöst, wenn auf die Sammlung HttpRequest.ServerVariables zugegriffen wird. Dies zeigt, dass diese beiden Sammlungen zwar fast identisch zu sein scheinen, aber die eine auf Anfragedaten durch Sicherheitsüberprüfungen zugreift und die andere nicht.

1voto

dpant Punkte 1455

Zu guter Letzt sei noch darauf hingewiesen, dass ASP.NET Data Binding-Steuerelemente automatisch verschlüsseln Werte während der Datenbindung. Dies ändert das Standardverhalten aller ASP.NET-Steuerelemente (TextBox, Label usw.), die in der Datei ItemTemplate . Das folgende Beispiel demonstriert ( ValidateRequest auf false gesetzt ist):

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 dahinter

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. Fall einen Wert vorlegen: &#39;

Label1.Text Wert: &#39;

TextBox2.Text Wert: &amp;#39;

  1. Fall einen Wert vorlegen: <script>alert('attack!');</script>

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

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

1voto

Peter Punkte 34999

Für diejenigen unter uns, die immer noch an Webformularen festhalten, habe ich die folgende Lösung gefunden, die es Ihnen ermöglicht, die Validierung nur für ein Feld zu deaktivieren! (Ich würde es hassen, sie für die ganze 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 sollten alle Zeichen erlaubt sein (dies ist perfekt für Passwortfelder!)

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