it-swarm-eu.dev

Un valore Request.Form potenzialmente pericoloso è stato rilevato dal client

Ogni volta che un utente pubblica qualcosa che contiene < o > in una pagina della mia applicazione web, ottengo questa eccezione generata.

Non voglio entrare nella discussione sull'abilità di lanciare un'eccezione o di bloccare un'intera applicazione web perché qualcuno ha inserito un personaggio in una casella di testo, ma sto cercando un modo elegante per gestirlo.

Intrappolare l'eccezione e mostrare

Si è verificato un errore, torna indietro e digita nuovamente l'intero modulo, ma questa volta non utilizzare <

non mi sembra abbastanza professionale.

La disabilitazione della convalida post (validateRequest="false") eviterà sicuramente questo errore, ma lascerà la pagina vulnerabile a un numero di attacchi.

Idealmente: quando si verifica un postback contenente caratteri HTML limitati, il valore inserito nella raccolta Form verrà automaticamente codificato in HTML . Quindi la proprietà .Text della mia casella di testo sarà something & lt; html & gt;

C'è un modo per farlo da un conduttore?

1379
Radu094

Penso che tu stia attaccando da un angolo sbagliato cercando di codificare tutti i dati inviati.

Si noti che un "<" potrebbe anche provenire da altre fonti esterne, come un campo di database, una configurazione, un file, un feed e così via. 

Inoltre, "<" non è intrinsecamente pericoloso. È pericoloso solo in un contesto specifico: quando si scrivono stringhe che non sono state codificate in output HTML (a causa dell'XSS).

In altri contesti, diverse sottostringhe sono pericolose, ad esempio, se si scrive un URL fornito dall'utente in un collegamento, la sottostringa "javascript:" potrebbe essere pericolosa. D'altra parte, il carattere di virgoletta singola è pericoloso quando si interpolano stringhe nelle query SQL, ma perfettamente sicuro se fa parte di un nome inviato da un modulo o letto da un campo di database.

La linea di fondo è: non puoi filtrare input casuali per personaggi pericolosi, perché qualsiasi personaggio può essere pericoloso nelle giuste circostanze. Dovresti codificare nel punto in cui alcuni personaggi specifici possono diventare pericolosi perché attraversano una sotto-lingua diversa in cui hanno un significato speciale. Quando scrivi una stringa in HTML, dovresti codificare i caratteri che hanno un significato speciale in HTML, usando Server.HtmlEncode. Se passi una stringa ad un'istruzione SQL dinamica, dovresti codificare caratteri diversi (o meglio, lasciare che il framework faccia per te usando istruzioni preparate o simili) ..

Quando sei sicuro di codificare HTML ovunque passi le stringhe in HTML, quindi imposta validateRequest="false" nella direttiva <%@ Page ... %> nei tuoi file .aspx.

In .NET 4 potrebbe essere necessario fare un po 'di più. A volte è necessario aggiungere anche <httpRuntime requestValidationMode="2.0" /> a web.config ( reference ).

1028
JacquesB

Esiste una soluzione diversa a questo errore se si utilizza ASP.NET MVC:

Campione C #:

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

Esempio di Visual Basic:

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

In ASP.NET MVC (a partire dalla versione 3), è possibile aggiungere l'attributo AllowHtml a una proprietà sul modello.

Consente a una richiesta di includere il markup HTML durante l'associazione del modello ignorando la convalida della richiesta per la proprietà.

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

Se sei su .NET 4.0 assicurati di aggiungerlo nel tuo file web.config all'interno dei tag <system.web>:

<httpRuntime requestValidationMode="2.0" />

In .NET 2.0, la convalida della richiesta si applicava solo alle richieste aspx. In .NET 4.0 questo è stato ampliato per includere tutte richieste. È possibile ripristinare only eseguendo la convalida XSS durante l'elaborazione di .aspx specificando:

requestValidationMode="2.0"

Puoi disabilitare la richiesta validate interamente specificando:

validateRequest="false"
206
JordanC

Per ASP.NET 4.0, è possibile consentire il markup come input per pagine specifiche anziché l'intero sito inserendo tutto in un elemento <location>. Questo assicurerà che tutte le altre pagine siano al sicuro. NON è necessario inserire ValidateRequest="false" nella tua pagina .aspx.

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

È più sicuro controllarlo all'interno di web.config, perché è possibile vedere a livello di sito quali pagine consentono il markup come input.

È ancora necessario convalidare in modo programmato l'input nelle pagine in cui la convalida della richiesta è disabilitata.

108
Carter Medlin

Le risposte precedenti sono grandiose, ma nessuno ha detto come escludere un singolo campo dall'essere validato per le iniezioni HTML/JavaScript. Non conosco le versioni precedenti, ma in MVC3 Beta puoi farlo:

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

Ciò convalida ancora tutti i campi eccetto quello escluso. La cosa bella di questo è che i tuoi attributi di convalida continuano a validare il campo, ma non ottieni il messaggio "Un valore potenzialmente pericoloso Request.Form è stato rilevato dal client" eccezioni.

L'ho usato per convalidare un'espressione regolare. Ho creato il mio ValidationAttribute per vedere se l'espressione regolare è valida o meno. Poiché le espressioni regolari possono contenere qualcosa che assomiglia a uno script, ho applicato il codice precedente: l'espressione regolare viene ancora controllata se è valida o meno, ma non se contiene script o HTML.

70
gligoran

In ASP.NET MVC è necessario impostare requestValidationMode = "2.0" e validateRequest = "false" in web.config e applicare un attributo ValidateInput all'azione del controller:

<httpRuntime requestValidationMode="2.0"/>

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

e

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

Puoi codificare HTML contenuto della casella di testo, ma sfortunatamente ciò non impedirà l'esecuzione dell'eccezione. Nella mia esperienza non c'è modo, e devi disabilitare la convalida della pagina. In questo modo stai dicendo: "Starò attento, lo prometto".

45
Pavel Chuchuva

Per MVC, ignorare la convalida dell'input aggiungendo 

[ValidateInput (false)]

sopra ogni azione nel controller.

42
A.Dara

È possibile rilevare l'errore in Global.asax. Voglio ancora convalidare, ma mostrare un messaggio appropriato. Nel blog elencato di seguito, è disponibile un esempio simile. 

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

Il reindirizzamento a un'altra pagina sembra anche una risposta ragionevole all'eccezione.

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

41
BenMaddox

Tieni presente che alcuni controlli .NET codificheranno automaticamente l'output in HTML. Ad esempio, l'impostazione della proprietà .Text su un controllo TextBox verrà automaticamente codificata. Ciò significa in particolare convertire < in &lt;, > in &gt; e & in &amp;. Quindi diffidare di fare questo ...

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

Tuttavia, la proprietà .Text per HyperLink, Literal e Label non codificherà HTML, quindi avvolgerà Server.HtmlEncode (); tutto ciò che viene impostato su queste proprietà è indispensabile se si desidera impedire che <script> window.location = "http://www.google.com"; </script> venga emesso nella pagina e successivamente eseguito.

Fai qualche esperimento per vedere cosa viene codificato e cosa no.

33
Dominic Pettifer

La risposta a questa domanda è semplice:

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

Ciò disabilita la convalida per la richiesta particolare.

31
flakomalo

Nel file web.config, all'interno dei tag, inserire l'elemento httpRuntime con l'attributo requestValidationMode = "2.0". Aggiungi anche l'attributo validateRequest = "false" nell'elemento pages.

Esempio:

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

Se non si desidera disabilitare ValidateRequest è necessario implementare una funzione JavaScript per evitare l'eccezione. Non è l'opzione migliore, ma funziona.

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

Quindi, nel codice sottostante, nell'evento PageLoad, aggiungi l'attributo al tuo controllo con il codice successivo:

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

Sembra che nessuno abbia ancora menzionato il sotto, ma risolve il problema per me. E prima che qualcuno dica sì, è Visual Basic ... schifo.

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

Non so se ci sono degli svantaggi, ma per me questo ha funzionato in modo sorprendente.

20
Piercy

Un'altra soluzione è:

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

Se stai usando framework 4.0, allora la voce nel web.config (<pages validateRequest = "false" />)

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

Se stai utilizzando framework 4.5, la voce in web.config (requestValidationMode = "2.0")

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

Se vuoi una sola pagina allora, nel tuo file aspx dovresti mettere la prima riga come questa:

<%@ Page EnableEventValidation="false" %>

se hai già qualcosa come <% @ Page quindi aggiungi il resto => EnableEventValidation="false"%>

Raccomando di non farlo.

14
Durgesh Pandey

In ASP.NET, puoi prendere l'eccezione e fare qualcosa al riguardo, come visualizzare un messaggio amichevole o reindirizzare ad un'altra pagina ... Inoltre c'è la possibilità che tu possa gestire la validazione da solo ...

Visualizza messaggio amichevole:

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

Immagino che potresti farlo in un modulo; ma questo lascia aperte alcune domande; cosa succede se si desidera salvare l'input in un database? All'improvviso, poiché stai salvando i dati codificati nel database, finisci per fidarti dell'input che è probabilmente una cattiva idea. Idealmente si memorizzano i dati non codificati grezzi nel database e la codifica ogni volta.

Disabilitare la protezione a livello di pagina e quindi codificare ogni volta è un'opzione migliore.

Anziché utilizzare Server.HtmlEncode, è necessario consultare la più recente/più completa libreria Anti-XSS del team Microsoft ACE.

12
blowdart

Le altre soluzioni qui sono belle, tuttavia è un po 'un dolore reale nella parte posteriore di dover applicare [AllowHtml] a ogni singola proprietà del modello, soprattutto se si dispone di oltre 100 modelli su un sito di dimensioni decenti.

Se come me, vuoi trasformare questa funzione (IMHO piuttosto inutile) fuori dal sito, puoi sovrascrivere il metodo Execute () nel tuo controller di base (se non hai già un controller di base ti consiglio di crearne uno, possono essere abbastanza utile per l'applicazione di funzionalità comuni).

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

Assicurati di essere in grado di codificare in HTML tutto ciò che viene pompato nelle viste che provengono dall'input dell'utente (è comunque il comportamento predefinito in ASP.NET MVC 3 con Razor, quindi a meno che per qualche strana ragione tu stia usando Html.Raw () tu non dovrebbe richiedere questa funzione.

10
magritte

Disattiva la convalida della pagina se hai veramente bisogno dei caratteri speciali come, >, <, ecc. Quindi assicurati che quando l'input dell'utente viene visualizzato, i dati siano codificati in HTML. 

Esiste una vulnerabilità di sicurezza con la convalida della pagina, quindi può essere aggirata. Inoltre, la convalida della pagina non deve essere esclusivamente basata.

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

9
woany

Causa

ASP.NET per impostazione predefinita convalida tutti i controlli di input per contenuti potenzialmente non sicuri che possono portare a cross-site scripting (XSS) e Iniezioni SQL . In questo modo non consente tale contenuto lanciando l'eccezione di cui sopra. Per impostazione predefinita si consiglia di consentire che questo controllo si verifichi su ogni postback.

Soluzione

In molte occasioni è necessario inviare contenuto HTML alla tua pagina tramite Rich TextBoxes o Rich Text Editors. In tal caso puoi evitare questa eccezione impostando il tag ValidateRequest nella direttiva @Page su false.

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

Ciò disabiliterà la convalida delle richieste per la pagina che hai impostato il flag ValidateRequest su false. Se vuoi disabilitarlo, controlla tutta la tua applicazione web; dovrai impostarlo su false nella sezione web.config <system.web>

<pages validateRequest ="false" />

Per i framework .NET 4.0 o versioni successive è necessario aggiungere anche la seguente riga nella sezione <system.web> per eseguire il lavoro sopra.

<httpRuntime requestValidationMode = "2.0" />

Questo è tutto. Spero che questo ti aiuti a liberarti di questo problema.

Riferimento da: Errore ASP.Net: è stato rilevato un valore Request.Form potenzialmente pericoloso dal client

9
vakeel

Ho trovato una soluzione che utilizza JavaScript per codificare i dati, che viene decodificato in .NET (e non richiede jQuery).

  • Rendi la casella di testo un elemento HTML (come textarea) invece di uno ASP.
  • Aggiungi un campo nascosto.
  • Aggiungi la seguente funzione JavaScript alla tua intestazione.

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

Nella tua textarea, includi un onchange che chiama boo ():

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

Infine, in. NET, usa

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

Sono consapevole che questo è a senso unico: se hai bisogno di un doppio senso devi essere creativo, ma questo fornisce una soluzione se non puoi modificare il web.config

Ecco un esempio I (MC9000) fornito con 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
    });


});

E il markup:

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

Funziona alla grande Se un hacker tenta di postare bypassando JavaScript, vedrà semplicemente l'errore. È possibile salvare tutti i dati codificati in un database, quindi decifrarli (sul lato server) e analizzare e controllare gli attacchi prima di visualizzarli altrove.

9
Jason Shuler

Stavo ottenendo anche questo errore.

Nel mio caso, un utente ha inserito un carattere accentato á in un nome ruolo (relativo al provider di appartenenze ASP.NET).

Ho passato il nome del ruolo a un metodo per concedere gli utenti a quel ruolo e la richiesta del post $.ajax stava fallendo miseramente ...

L'ho fatto per risolvere il problema:

Invece di

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

Fai questo

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

@Html.Raw ha fatto il trucco.

Stavo ottenendo il nome del ruolo come valore HTML roleName="Cadastro b&#225;s". Questo valore con entità HTML &#225; era bloccato da ASP.NET MVC. Ora ottengo il valore del parametro roleName nel modo in cui dovrebbe essere: roleName="Cadastro Básico" e il motore ASP.NET MVC non bloccherà più la richiesta.

9

Puoi anche usare la funzione JavaScript escape (stringa) per sostituire i caratteri speciali. Quindi lato server utilizzare Server. URLDecode (stringa) per tornare indietro.

In questo modo non è necessario disattivare la convalida dell'input e sarà più chiaro agli altri programmatori che la stringa potrebbe avere contenuto HTML.

7
Trisped

Ho finito per usare JavaScript prima di ogni postback per verificare i caratteri che non volevi, come ad esempio:

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

A mio parere, la mia pagina è per lo più data entry e ci sono pochissimi elementi che fanno postback, ma almeno i loro dati vengono mantenuti.

6
Ryan

Finché questi sono solo "<" e ">" (e non la doppia citazione stessa) e li stai usando in un contesto come <input value = "this" />, tu sei sicuro (mentre per <textarea> this one </ textarea> saresti ovviamente vulnerabile). Ciò potrebbe semplificare la tua situazione, ma per qualsiasi cosa più usare una delle altre soluzioni pubblicate.

4
Paweł Hajdan

Se stai solo cercando di dire ai tuoi utenti che <and> non devono essere usati MA, non vuoi che l'intero modulo sia processato/postato (e perdi tutto l'input) prima non potresti semplicemente inserire un validatore in tutto il campo per lo screening di quelli (e forse di altri personaggi potenzialmente pericolosi)?

4
Captain Toad

Puoi usare qualcosa come:

var nvc = Request.Unvalidated().Form;

Più tardi, nvc["yourKey"] dovrebbe funzionare.

4
Ady Levy

Nessuno dei suggerimenti ha funzionato per me. Non volevo disattivare comunque questa funzionalità per l'intero sito Web perché il 99% del tempo non desidera che i miei utenti inseriscano l'HTML nei moduli Web. Ho appena creato il mio lavoro attorno al metodo dato che sono l'unico a usare questa particolare applicazione. Converto l'input in HTML nel codice sottostante e lo inserisco nel mio database.

4
Mike S.

È possibile automaticamente il campo di codifica HTML in Raccoglitore modello personalizzato. La mia soluzione è diversa, ho inserito un errore in ModelState e ho visualizzato un messaggio di errore vicino al campo. È facile modificare questo codice per la codifica automatica 

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

Si noti che funziona solo per i campi modulo. Valore pericoloso non passato al modello del controllore, ma memorizzato in ModelState e può essere nuovamente visualizzato sul modulo con un messaggio di errore. 

I caratteri pericolosi nell'URL possono essere gestiti in questo modo:

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

È necessario utilizzare il metodo Server.HtmlEncode per proteggere il sito da input pericolosi.

Altre informazioni qui

3
bastos.sergio

Come indicato nel mio commento a Risposta di Sel , questa è la nostra estensione a un validatore di richieste personalizzate.

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

Per coloro che non utilizzano l'associazione modello, che stanno estraendo ogni parametro dal Request.Form, che sono sicuri che il testo di input non causerà danni, c'è un altro modo. Non è una grande soluzione, ma farà il lavoro. 

Dal lato client, codificalo come uri e poi invialo.
per esempio: 

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

Dal lato server, accettalo e decodificalo come uri.
per esempio: 

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

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

per favore cerca le differenze tra UrlDecode e UnescapeDataString

2
Wahid Masud

Ultimo ma non meno importante, si prega di notare che i binding di dati di ASP.NET controllano automaticamente codificare i valori durante l'associazione dei dati. Ciò modifica il comportamento predefinito di tutti i controlli ASP.NET (TextBox, Label ecc.) Contenuti in ItemTemplate. Il seguente esempio dimostra (ValidateRequest è impostato su false):

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 behind

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. Valore invio caso: &#39;

Label1.Text valore: &#39;

TextBox2.Text valore: &amp;#39;

  1. Case submit value: <script>alert('attack!');</script>

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

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

1
dpant

Per quelli di noi ancora bloccati su webforms ho trovato la seguente soluzione che ti permette di disabilitare solo la convalida su un campo! (Mi dispiacerebbe disabilitarla per l'intera pagina).

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

Ora usa solo <prefix:UnvalidatedTextBox id="test" runat="server" /> invece di <asp:TextBox, e dovrebbe consentire tutti i caratteri (questo è perfetto per i campi password!)

1
Peter

So che questa domanda riguarda la pubblicazione di moduli, ma vorrei aggiungere alcuni dettagli per le persone che hanno ricevuto questo errore in altre circostanze. Potrebbe anche verificarsi su un gestore utilizzato per implementare un servizio Web. 

Supponiamo che il tuo client web mandi POST o PUT richieste usando ajax e mandi json o xml text o raw (un file contenuto) al tuo servizio web. Poiché il tuo servizio web non ha bisogno di ottenere informazioni da un'intestazione Content-Type, il tuo codice JavaScript non ha impostato questa intestazione sulla tua richiesta Ajax. Ma se non si imposta questa intestazione su una richiesta ajax POST/PUT, Safari può aggiungere questa intestazione: "Content-Type: application/x-www-form-urlencoded". Ho osservato che su Safari 6 su iPhone, ma altre versioni di Safari/OS o Chrome potrebbero fare lo stesso. Pertanto, quando si riceve questa intestazione Content-Type parte di .NET Framework presuppone che la struttura dei dati del corpo della richiesta corrisponda a una registrazione in formato html mentre non lo fa e aumenta un'eccezione HttpRequestValidationException. La prima cosa da fare è ovviamente impostare sempre l'intestazione Content-Type su qualsiasi tipo tranne un tipo MIME su una richiesta ajax POST/PUT, anche se è inutile per il tuo servizio web.

Ho anche scoperto questo dettaglio:
In queste circostanze, l'eccezione HttpRequestValidationException viene aumentata quando il codice tenta di accedere alla raccolta HttpRequest.Params. Sorprendentemente, questa eccezione non viene aumentata quando accede alla raccolta HttpRequest.ServerVariables. Questo dimostra che mentre queste due raccolte sembrano essere quasi identiche, si accede ai dati delle richieste attraverso i controlli di sicurezza e l'altro no.

1
figolu

In .Net 4.0 e versioni successive, che è il solito caso, inserire le seguenti impostazioni in system.web

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

nel mio caso, usando asp: controllo Textbox (Asp.net 4.5), invece di impostare la pagina per validateRequest="false" che ho usato 

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

sulla casella di testo che ha causato l'eccezione.

0
maozx

Una soluzione

Non mi piace disattivare la convalida dei post (validateRequest = "false"). D'altra parte non è accettabile che l'applicazione si blocchi solo perché un utente innocente digita <x o qualcosa del genere. 

Pertanto ho scritto una funzione javascript lato client (xssCheckValidates) che effettua un controllo preliminare. Questa funzione è chiamata quando c'è un tentativo di inviare i dati del modulo, come questo:

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

La funzione è abbastanza semplice e potrebbe essere migliorata, ma sta facendo il suo lavoro.

Si prega di notare che lo scopo di questo non è quello di proteggere il sistema dall'hacking, ma è pensato per proteggere gli utenti da una brutta esperienza. La convalida della richiesta eseguita sul server è ancora attiva e questa è (parte della) protezione del sistema (nella misura in cui è in grado di farlo). 

La ragione per cui dico "parte di" qui è perché ho sentito che la convalida della richiesta integrata potrebbe non essere sufficiente, quindi altri mezzi complementari potrebbero essere necessari per avere una protezione completa. Ma, ancora, la funzione javascript che presento qui ha nothing a che fare con la protezione del sistema. È only pensato per assicurarsi che gli utenti non abbiano una brutta esperienza.

Puoi provarlo qui:

    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
Magnus

Usa il Server.HtmlEncode("yourtext");

0
Voigt

Vedo che c'è molto scritto su questo ... e non ho visto questo menzionato . Questo è disponibile da. NET Framework 4.5

L'opzione ValidateRequestMode per un controllo è una grande opzione . In questo modo gli altri controlli sulla pagina sono ancora protetti. Nessuna modifica web.config necessaria.

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