Er is een potentieel gevaarlijke Request.Form-waarde gedetecteerd van de client

Telkens wanneer een gebruiker iets plaatst met <of >op een pagina in mijn webtoepassing, krijg ik deze uitzondering.

Ik wil niet ingaan op de discussie over de slimheid van het maken van een uitzondering of het crashen van een hele webtoepassing omdat iemand een teken in een tekstvak heeft ingevoerd, maar ik ben op zoek naar een elegante manier om dit aan te pakken.

p>

De uitzondering overslaan en weergeven

Er is een fout opgetreden, ga terug en typ uw volledige formulier opnieuw, maar gebruik deze keer niet <

lijkt me niet professioneel genoeg.

Het uitschakelen van postvalidatie (ValidateRequest="false") zal deze fout zeker voorkomen, maar de pagina blijft kwetsbaar voor een aantal aanvallen.

Ideaal: wanneer een terugpost plaatsvindt met HTML-beperkte tekens, wordt die geposte waarde in de formulierverzameling automatisch HTML-gecodeerd.
Dus de eigenschap .Textvan mijn tekstvak zal something & lt; html & gt;

Is er een manier waarop ik dit kan doen vanuit een handler?


Antwoord 1, autoriteit 100%

Ik denk dat je het vanuit de verkeerde hoek aanvalt door te proberen alle geposte gegevens te coderen.

Houd er rekening mee dat een “<” ook van andere externe bronnen kan komen, zoals een databaseveld, een configuratie, een bestand, een feed enzovoort.

Bovendien is “<” niet inherent gevaarlijk. Het is alleen gevaarlijk in een specifieke context: bij het schrijven van strings die niet zijn gecodeerd naar HTML-uitvoer (vanwege XSS).

In andere contexten zijn verschillende substrings gevaarlijk, bijvoorbeeld als u een door de gebruiker verstrekte URL in een link schrijft, kan de substring “javascript:” gevaarlijk zijn. Het enkele aanhalingsteken aan de andere kant is gevaarlijk bij het interpoleren van strings in SQL-query’s, maar volkomen veilig als het een onderdeel is van een naam die is ingediend vanaf een formulier of wordt gelezen uit een databaseveld.

Waar het op neerkomt is: je kunt willekeurige invoer niet filteren op gevaarlijke tekens, omdat elk teken onder de juiste omstandigheden gevaarlijk kan zijn. Je moet coderen op het punt waar sommige specifieke karakters gevaarlijk kunnen worden omdat ze overgaan in een andere subtaal waar ze een speciale betekenis hebben. Wanneer u een tekenreeks naar HTML schrijft, moet u tekens coderen die een speciale betekenis hebben in HTML, met behulp van Server.HtmlEncode. Als u een string doorgeeft aan een dynamische SQL-instructie, moet u verschillende tekens coderen (of beter, laat het framework dit voor u doen door voorbereide instructies of iets dergelijks te gebruiken).

Alsje zeker weet dat je overal HTML-codeert waar je strings doorgeeft aan HTML, stel dan ValidateRequest="false"in op de <%@ Page ... %>richtlijn in uw .aspxbestand(en).

In .NET 4 moet u misschien iets meer doen. Soms is het nodig om ook <httpRuntime requestValidationMode="2.0" />toe te voegen aan web.config (referentie).


Antwoord 2, autoriteit 46%

Er is een andere oplossing voor deze fout als u ASP.NET MVC gebruikt:

C#-voorbeeld:

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

Visual Basic-voorbeeld:

<AcceptVerbs(HttpVerbs.Post), ValidateInput(False)> _
Function Edit(ByVal collection As FormCollection) As ActionResult
    ...
End Function

Antwoord 3, autoriteit 39%

In ASP.NET MVC (vanaf versie 3) kunt u de AllowHtml-kenmerk aan een eigenschap op uw model.

Hiermee kan een verzoek worden ingediend om HTML-opmaak op te nemen tijdens de modelbinding door de verzoekvalidatie voor de eigenschap over te slaan.

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

Antwoord 4, autoriteit 19%

Als u .NET 4.0 gebruikt, zorg er dan voor dat u dit toevoegt aan uw web.config-bestand binnen de <system.web>-tags:

<httpRuntime requestValidationMode="2.0" />

In .NET 2.0 werd verzoekvalidatie alleen toegepast op aspx-verzoeken. In .NET 4.0 is dit uitgebreid met alleverzoeken. U kunt terugkeren naar het alleenuitvoeren van XSS-validatie bij het verwerken van .aspxdoor het volgende op te geven:

requestValidationMode="2.0"

U kunt het valideren van verzoek geheeluitschakelen door het volgende op te geven:

validateRequest="false"

Antwoord 5, autoriteit 10%

Voor ASP.NET 4.0 kunt u markup toestaan ​​als invoer voor specifieke pagina’s in plaats van de hele site door alles in een <location>-element te plaatsen. Dit zorgt ervoor dat al uw andere pagina’s veilig zijn. U hoeft ValidateRequest="false"NIET op uw .aspx-pagina te plaatsen.

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

Het is veiliger om dit in uw web.config te beheren, omdat u op siteniveau kunt zien op welke pagina’s markeringen als invoer zijn toegestaan.

Je moet de invoer nog steeds programmatisch valideren op pagina’s waar validatie van verzoeken is uitgeschakeld.


Antwoord 6, autoriteit 7%

De eerdere antwoorden zijn geweldig, maar niemand heeft gezegd hoe je een enkel veld kunt uitsluiten van validatie voor HTML/JavaScript-injecties. Ik weet niets van eerdere versies, maar in MVC3 Beta kun je dit doen:

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

Dit valideert nog steeds alle velden behalve de uitgesloten. Het leuke hiervan is dat je validatieattributen het veld nog steeds valideren, maar je krijgt gewoon niet de uitzonderingen “Er is een potentieel gevaarlijke Request.Form-waarde gedetecteerd door de client”.

Ik heb dit gebruikt om een ​​reguliere expressie te valideren. Ik heb mijn eigen ValidationAttribute gemaakt om te zien of de reguliere expressie geldig is of niet. Omdat reguliere expressies iets kunnen bevatten dat op een script lijkt, heb ik de bovenstaande code toegepast – de reguliere expressie wordt nog steeds gecontroleerd of deze geldig is of niet, maar niet of deze scripts of HTML bevat.


Antwoord 7, autoriteit 5%

In ASP.NET MVC moet u requestValidationMode=”2.0″ en validRequest=”false” in web.config instellen en een ValidateInput-kenmerk toepassen op uw controlleractie:

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

en

[Post, ValidateInput(false)]
public ActionResult Edit(string message) {
    ...
}

Antwoord 8, autoriteit 4%

Je kunt HTML-coderentekst doosinhoud, maar helaas zal dat de uitzondering niet voorkomen. In mijn ervaring kun je er niet omheen en moet je paginavalidatie uitschakelen. Door dat te doen, zeg je: “Ik zal voorzichtig zijn, dat beloof ik.”


Antwoord 9, autoriteit 4%

Het antwoord op deze vraag is eenvoudig:

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

Dit zou de validatie voor het specifieke verzoek uitschakelen.


Antwoord 10, autoriteit 4%

Je kunt die fout opvangen in Global.asax. Ik wil nog steeds valideren, maar een gepast bericht tonen. Op de onderstaande blog was een voorbeeld als dit beschikbaar.

   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();
        }
    }

Omleiden naar een andere pagina lijkt ook een redelijke reactie op de uitzondering.

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


Antwoord 11, autoriteit 4%

Voor MVC, negeer invoervalidatie door

. toe te voegen

[ValidateInput(false)]

boven elke actie in de controller.


Antwoord 12, autoriteit 3%

Houd er rekening mee dat sommige .NET-besturingselementen de uitvoer automatisch HTML-coderen. Als u bijvoorbeeld de eigenschap .Text op een TextBox-besturingselement instelt, wordt deze automatisch gecodeerd. Dat betekent specifiek het omzetten van <in &lt;, >in &gt;en &in &amp;. Dus wees op uw hoede om dit te doen…

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

De .Text-eigenschap voor HyperLink, Literal en Label zal echter geen HTML-coderen, dus wordt Server.HtmlEncode(); rond alles dat op deze eigenschappen wordt ingesteld, is een must als u wilt voorkomen dat <script> window.location = "http://www.google.com"; </script>niet naar uw pagina worden uitgevoerd en vervolgens worden uitgevoerd.

Probeer een beetje om te zien wat wel en niet wordt gecodeerd.


Antwoord 13, autoriteit 3%

Voer in het bestand web.config, binnen de tags, het httpRuntime-element in met het kenmerk requestValidationMode=”2.0″. Voeg ook het kenmerk validRequest=”false” toe aan het pagina-element.

Voorbeeld:

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

Antwoord 14, autoriteit 2%

Als u ValidateRequest niet wilt uitschakelen, moet u een JavaScript-functie implementeren om de uitzondering te voorkomen. Het is niet de beste optie, maar het werkt.

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

Voeg vervolgens in code achter, op de PageLoad-gebeurtenis, het kenmerk toe aan uw besturingselement met de volgende code:

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

Antwoord 15, autoriteit 2%

Het lijkt erop dat nog niemand het onderstaande heeft genoemd, maar het probleem is voor mij opgelost. En voordat iemand ja zegt, het is Visual Basic… bah.

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

Ik weet niet of er nadelen zijn, maar voor mij werkte dit geweldig.


Antwoord 16, autoriteit 2%

Een andere oplossing is:

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

Antwoord 17

Als u framework 4.0 gebruikt, dan is het item in de web.config (<pagesvalidRequest=”false” />)

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

Als u framework 4.5 gebruikt, dan is het item in de web.config (requestValidationMode=”2.0″)

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

Als u slechts één pagina wilt, moet u in uw aspx-bestand de eerste regel als volgt plaatsen:

<%@ Page EnableEventValidation="false" %>

als je al iets als <%@ pagina hebt, voeg dan gewoon de rest toe => EnableEventValidation="false"%>

Ik raad aan om het niet te doen.


Antwoord 18

In ASP.NET kun je de uitzondering opvangen en er iets aan doen, zoals een vriendelijk bericht weergeven of doorverwijzen naar een andere pagina… Ook is er een mogelijkheid dat je de validatie zelf kunt afhandelen…

Bekijk vriendelijk bericht:

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();
    }
}

Antwoord 19

Ik denk dat je het in een module zou kunnen doen; maar dat laat enkele vragen open; wat als u de invoer in een database wilt opslaan? Omdat u gecodeerde gegevens in de database opslaat, vertrouwt u plotseling op de invoer ervan, wat waarschijnlijk een slecht idee is. In het ideale geval slaat u onbewerkte ongecodeerde gegevens op in de database en de codering elke keer.

Het is een betere optie om de beveiliging op paginaniveau uit te schakelen en vervolgens elke keer te coderen.

In plaats van Server.HtmlEncode te gebruiken, moet u kijken naar de nieuwere, completere Anti-XSS-bibliotheekvan het Microsoft ACE-team.


Antwoord 20

Ik heb een oplossing gevonden die JavaScript gebruikt om de gegevens te coderen, die worden gedecodeerd in .NET (en geen jQuery vereist).

  • Maak van het tekstvak een HTML-element (zoals textarea) in plaats van een ASP-element.
  • Voeg een verborgen veld toe.
  • Voeg de volgende JavaScript-functie toe aan uw koptekst.

    functie boe() {
    targetText = document.getElementById(“HiddenField1”);
    sourceText = document.getElementById(“gebruikersbox”);
    targetText.value = escape(sourceText.innerText);
    }

In uw tekstgebied, voeg een onchange toe die boo() aanroept:

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

Tot slot, in .NET, gebruik

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

Ik ben me ervan bewust dat dit eenrichtingsverkeer is – als je tweerichtingsverkeer nodig hebt, moet je creatief zijn, maar dit biedt een oplossing als je de web.config niet kunt bewerken

Hier is een voorbeeld dat ik (MC9000) bedacht en gebruik via 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
    });
});

En de opmaak:

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

Dit werkt prima. Als een hacker probeert te posten via het omzeilen van JavaScript, zien ze alleen de fout. U kunt al deze gegevens ook gecodeerd in een database opslaan, deze vervolgens ongedaan maken (aan de serverzijde) en ontleden & controleer op aanvallen voordat u deze ergens anders weergeeft.


Antwoord 21

Oorzaak

ASP.NET valideert standaard alle invoercontroles voor mogelijk onveilige inhoud die kan leiden tot cross-site scripting(XSS) en SQL-injecties. Het verbiedt dergelijke inhoud dus door de bovenstaande uitzondering te maken. Standaard wordt aanbevolen om deze controle bij elke postback te laten plaatsvinden.

Oplossing

Vaak moet u HTML-inhoud naar uw pagina sturen via Rich TextBoxes of Rich Text Editors. In dat geval kunt u deze uitzondering vermijden door de ValidateRequest-tag in de @Page-instructie in te stellen op false.

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

Hiermee wordt de validatie van verzoeken uitgeschakeld voor de pagina waarvoor u de ValidateRequest-vlag op false hebt ingesteld. Als je dit wilt uitschakelen, controleer dan in je hele webapplicatie; je moet het op false zetten in je web.config <system.web> sectie

<pages validateRequest ="false" />

Voor .NET 4.0 of hoger frameworks moet u ook de volgende regel toevoegen in de <system.web> sectie om het bovenstaande te laten werken.

<httpRuntime requestValidationMode = "2.0" />

Dat is het. Ik hoop dat dit je helpt om van het bovenstaande probleem af te komen.

Referentie door: ASP.Net-fout: er is een potentieel gevaarlijke Request.Form-waarde gedetecteerd van de client


Antwoord 22

De andere oplossingen hier zijn leuk, maar het is een beetje vervelend om [AllowHtml] toe te passen op elke eigenschap van een model, vooral als je meer dan 100 modellen hebt op een site van behoorlijk formaat.

Als je, net als ik, deze (IMHO vrij zinloze) functie buiten de hele site wilt zetten, kun je de Execute()-methode in je basiscontroller overschrijven (als je nog geen basiscontroller hebt, raad ik je aan er een te maken, ze kunnen erg handig zijn voor het toepassen van algemene functionaliteit).

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

Zorg er wel voor dat je alles codeert in HTML wat naar de weergaven wordt gepompt die afkomstig zijn van gebruikersinvoer (het is sowieso standaardgedrag in ASP.NET MVC 3 met Razor, dus tenzij je om de een of andere bizarre reden Html.Raw gebruikt () u zou deze functie niet nodig moeten hebben.


Antwoord 23

Ik kreeg deze fout ook.

In mijn geval heeft een gebruiker een geaccentueerd teken aingevoerd in een rolnaam (met betrekking tot de ASP.NET-lidmaatschapsprovider).

Ik geef de rolnaam door aan een methode om Gebruikers die rol toe te kennen en het $.ajaxpostverzoek mislukte jammerlijk…

Ik heb dit gedaan om het probleem op te lossen:

In plaats van

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

Doe dit

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

@Html.Rawdeed het.

Ik kreeg de rolnaam als HTML-waarde roleName="Cadastro b&#225;s". Deze waarde met HTML-entiteit &#225;werd geblokkeerd door ASP.NET MVC. Nu krijg ik de parameterwaarde roleNamezoals het zou moeten zijn: roleName="Cadastro Basico"en de ASP.NET MVC-engine blokkeren het verzoek niet meer.


Antwoord 24

Schakel de paginavalidatie uit als u de speciale tekens zoals >, , <, enz. echt nodig hebt. Zorg er vervolgens voor dat wanneer de gebruikersinvoer wordt weergegeven, de gegevens zijn HTML-gecodeerd.

Er is een beveiligingsprobleem met de paginavalidatie, dus deze kan worden omzeild. Er moet ook niet alleen op de paginavalidatie worden vertrouwd.

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


Antwoord 25

Je zou ook de escape(string)-functie van JavaScript kunnen gebruiken om de speciale tekens te vervangen. Gebruik dan Server.URLDecode(string)om het terug te schakelen.

Op deze manier hoeft u invoervalidatie niet uit te schakelen en is het voor andere programmeurs duidelijker dat de tekenreeks HTML-inhoud kan hebben.


Antwoord 26

Uiteindelijk gebruikte ik JavaScript voor elke postback om te controleren op de tekens die je niet wilde, zoals:

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

Toegegeven, mijn pagina bestaat voornamelijk uit gegevensinvoer, en er zijn maar heel weinig elementen die postbacks uitvoeren, maar hun gegevens worden tenminste bewaard.


Antwoord 27

Je kunt zoiets gebruiken als:

var nvc = Request.Unvalidated().Form;

Later zou nvc["yourKey"]moeten werken.


Antwoord 28

Voor degenen die geen modelbinding gebruiken, die elke parameter uit het Request.Form extraheren en er zeker van zijn dat de invoertekst geen kwaad kan, is er een andere manier. Geen geweldige oplossing, maar het zal zijn werk doen.

Coder het vanaf de clientzijde als uri en verzend het vervolgens.
bijvoorbeeld:

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

Van serverkant, accepteer het en decodeer het als uri.
bijvoorbeeld:

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

of

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

zoek de verschillen tussen UrlDecodeen UnescapeDataString


Antwoord 29

Zolang deze alleen“<” zijn en “>” (en niet het dubbele aanhalingsteken zelf) tekens en je gebruikt ze in context zoals <input value=”this” />, je bent veilig (terwijl voor <textarea>deze</textarea> zou je natuurlijk kwetsbaar zijn). Dat kan je situatie vereenvoudigen, maar voor allesmeer gebruik je een van de andere geposte oplossingen.


Antwoord 30

Als u uw gebruikers gewoon wilt vertellen dat < en > mogen niet worden gebruikt MAAR u wilt niet dat het hele formulier van tevoren verwerkt/gepost wordt (en alle invoer kwijtraakt) zou u niet gewoon een validator in het veld kunnen plaatsen om te screenen op deze (en misschien andere potentieel gevaarlijke ) tekens?

Other episodes