Une valeur Request.Form potentiellement dangereuse a été détectée par le client

1471

Chaque fois qu'un utilisateur publie quelque chose contenant <ou >dans une page de mon application Web, cette exception est levée.

Je ne veux pas entrer dans la discussion sur l'intelligence de lever une exception ou de planter une application Web entière parce que quelqu'un a entré un caractère dans une zone de texte, mais je cherche une manière élégante de gérer cela.

Piéger l'exception et montrer

Une erreur est survenue, veuillez revenir en arrière et retaper votre formulaire entier à nouveau, mais cette fois, veuillez ne pas utiliser <

ne me semble pas assez professionnel.

La désactivation de la post-validation ( validateRequest="false") évitera certainement cette erreur, mais elle rendra la page vulnérable à un certain nombre d'attaques.

Idéalement: lorsqu'un message de retour contenant des caractères restreints HTML se produit, cette valeur publiée dans la collection Form sera automatiquement encodée en HTML. La .Textpropriété de ma zone de texte sera doncsomething & lt; html & gt;

Existe-t-il un moyen de le faire à partir d'un gestionnaire?

Radu094
la source
68
Notez que vous pouvez obtenir cette erreur si vous avez également des noms d'entité HTML (& amp;) ou des numéros d'entité (& # 39;).
Drew Noakes
18
Eh bien, puisque c'est ma question, je sens que je peux définir ce que le point est réellement: planter un processus de demande entier et renvoyer un message d'erreur générique parce que quelqu'un a tapé un «<» est exagéré. D'autant plus que vous savez que la plupart des gens vont juste 'validateRequest = false' pour s'en débarrasser,
rouvrant
7
@DrewNoakes: les noms d'entité (& amp;) ne semblent pas être un problème selon mes tests (testés dans .Net 4.0), bien que les numéros d'entité (& # 39;) échouent à la validation (comme vous l'avez dit). Si vous démontez la méthode System.Web.CrossSiteScriptingValidation.IsDangerousString à l'aide de .Net Reflector, vous verrez que le code recherche spécifiquement les balises html (commençant par <) et les numéros d'entité (commençant par & #)
Gyum Fox
5
Créez un nouveau site dans VS2014 à l'aide du projet MVC par défaut et exécutez-le. Cliquez sur le lien d'enregistrement, ajoutez un e-mail et utilisez "<P455-0r [!" comme mot de passe. Même erreur hors de la boîte, n'essayant pas de faire quoi que ce soit de malveillant, le champ de mot de passe ne sera pas affiché, donc ce ne sera pas une attaque XSS, mais la seule façon de le corriger est de supprimer complètement la validation avec ValidateInput (false) ? La suggestion AllowHtml ne fonctionne pas dans cette situation, a toujours explosé avec la même erreur. Une valeur Request.Form potentiellement dangereuse a été détectée par le client (Password = "<P455-0r [!").
stephenbayer
TL; DR mis <httpRuntime requestValidationMode="2.0" />dans web.config

Réponses:

1081

Je pense que vous l'attaquez du mauvais angle en essayant d'encoder toutes les données publiées.

Notez qu'un " <" peut également provenir d'autres sources externes, comme un champ de base de données, une configuration, un fichier, un flux, etc.

De plus, " <" n'est pas intrinsèquement dangereux. C'est seulement dangereux dans un contexte spécifique: lors de l'écriture de chaînes qui n'ont pas été encodées dans la sortie HTML (à cause de XSS).

Dans d'autres contextes, différentes sous-chaînes sont dangereuses. Par exemple, si vous écrivez une URL fournie par l'utilisateur dans un lien, la sous-chaîne " javascript:" peut être dangereuse. Le caractère guillemet simple, d'autre part, est dangereux lors de l'interpolation de chaînes dans des requêtes SQL, mais parfaitement sûr s'il fait partie d'un nom soumis à partir d'un formulaire ou lu dans un champ de base de données.

L'essentiel est: vous ne pouvez pas filtrer les entrées aléatoires pour les caractères dangereux, car n'importe quel caractère peut être dangereux dans les bonnes circonstances. Vous devez coder au point où certains caractères spécifiques peuvent devenir dangereux car ils se croisent dans une sous-langue différente où ils ont une signification particulière. Lorsque vous écrivez une chaîne en HTML, vous devez coder les caractères qui ont une signification particulière en HTML, à l'aide de Server.HtmlEncode. Si vous passez une chaîne à une instruction SQL dynamique, vous devez coder différents caractères (ou mieux, laissez le framework le faire pour vous en utilisant des instructions préparées ou similaires).

Lorsque vous êtes sûr de coder en HTML partout où vous passez des chaînes au HTML, définissez-les validateRequest="false"dans la <%@ Page ... %>directive dans votre ou vos .aspxfichiers.

Dans .NET 4, vous devrez peut-être en faire un peu plus. Parfois, il est également nécessaire d'ajouter <httpRuntime requestValidationMode="2.0" />à web.config ( référence ).

JacquesB
la source
74
Pour ceux qui arrivent en retard: validateRequest = "false" va dans la directive Page (première ligne de votre fichier .aspx)
MGOwen
56
Astuce: insérez <httpRuntime requestValidationMode="2.0" />une balise de localisation pour éviter de supprimer la protection utile fournie par la validation à partir du reste de votre site.
Brian
299
Dans MVC3, c'est [AllowHtml]sur la propriété du modèle.
Jeremy Holovacs, le
2
Pour le désactiver globalement pour MVC 3, vous avez également besoin GlobalFilters.Filters.Add(new ValidateInputAttribute(false));de Application_Start().
Alex
15
@MGOwen vous pouvez également ajouter la directive page au web.config via <pages validateRequest="false" />dans <system.web />. Cela appliquera la propriété à toutes les pages.
oliver-clare
504

Il existe une solution différente à cette erreur si vous utilisez ASP.NET MVC:

Échantillon C #:

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

Exemple Visual Basic:

<AcceptVerbs(HttpVerbs.Post), ValidateInput(False)> _
Function Edit(ByVal collection As FormCollection) As ActionResult
    ...
End Function
Zack Peterson
la source
le problème peut arriver quand il est nécessaire sur une page de la demande complète
3
Vous pouvez également ajouter l'attribut [ValidateInput (false)] au niveau de la classe. Si vous l'ajoutez à votre classe de contrôleur de base, il s'appliquera à toutes les actions de méthode de contrôleur.
Shan Plourde
@Zack Merci pour la solution. D'un autre côté, je me demande si [AllowHtml]c'est mieux que ValidateInput(false), car [AllowHtml]est défini à la fois pour une propriété, c'est-à-dire un champ Editor et chaque fois qu'il est utilisé, il n'est pas nécessaire de l'utiliser pour plusieurs actions. Que suggérez-vous?
Jack
@Zack Peterson Est-il sûr d'utiliser? Pas de problème de sécurité?
shrey Pav
417

Dans ASP.NET MVC (à partir de la version 3), vous pouvez ajouter l' AllowHtmlattribut à une propriété de votre modèle.

Il permet à une demande d'inclure un balisage HTML lors de la liaison du modèle en ignorant la validation de la demande pour la propriété.

[AllowHtml]
public string Description { get; set; }
Anthony Johnston
la source
12
C'est bien mieux de le faire de manière déclarative que dans le contrôleur!
Andiih
29
La seule bonne réponse! la désactivation de la validation sur l'action du contrôleur est hacky. Et pour désactiver la validation au niveau de l'application, les développeurs doivent être suspendus!
trailmax
Est-ce que cela a disparu dans MVC 4?
granadaCoder
1
Quelle est la difference entre ValidateInput(false)et AllowHtml? Quel est l'avantage de l'un sur l'autre? Quand voudrais-je utiliser à la AllowHtmlplace de ValidateInput(false)? Quand voudrais-je utiliser ValidateInput(false)plus AllowHtml? Quand voudrais-je utiliser les deux? Est-il judicieux d'utiliser les deux?
Ian Boyd
3
ValidateInput est sur la méthode, AllowHtml est sur la propriété du modèle - donc vous n'autorisez que celui que vous pensez avoir en html - pas tous
Anthony Johnston
213

Si vous êtes sur .NET 4.0, assurez-vous de l'ajouter dans votre fichier web.config à l'intérieur des <system.web>balises:

<httpRuntime requestValidationMode="2.0" />

Dans .NET 2.0, la validation des demandes ne s'appliquait qu'aux aspxdemandes. Dans .NET 4.0, cela a été étendu pour inclure toutes les demandes. Vous pouvez revenir à la validation XSS uniquement lors du traitement .aspxen spécifiant:

requestValidationMode="2.0"

Vous pouvez désactiver entièrement la validation de la demande en spécifiant:

validateRequest="false"
JordanC
la source
30
À l'intérieur des <system.web>balises.
Hosam Aly
8
J'ai mis cela dans le web.config, mais toujours à l'erreur "Une valeur Request.Form potentiellement dangereuse"
Filip
20
Il semble que <httpRuntime requestValidationMode = "2.0" /> ne fonctionne que lorsque le framework 2.0 est installé sur la machine. Que faire si le framework 2.0 n'est pas installé du tout mais que seul le framework 4.0 est installé?
Samuel
Cela a totalement fonctionné pour moi. Aucune des étapes documentées dans les autres réponses n'était nécessaire (y compris validateRequest = "false")!
tom redfern
112

Pour ASP.NET 4.0, vous pouvez autoriser le balisage en entrée pour des pages spécifiques au lieu de l'ensemble du site en plaçant le tout dans un <location>élément. Cela garantira que toutes vos autres pages sont en sécurité. Vous n'avez PAS besoin de mettre ValidateRequest="false"votre page .aspx.

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

Il est plus sûr de contrôler cela dans votre web.config, car vous pouvez voir au niveau du site quelles pages autorisent le balisage en entrée.

Vous devez toujours valider par programmation l'entrée sur les pages où la validation de la demande est désactivée.

Carter Medlin
la source
Plus d'informations sur requestValidationMode = 2 | 4 ici: msdn.microsoft.com/en-us/library/…
GlennG
Malheureusement, cela ne fonctionnera pas avec ASP.net 2.0 tel quel. Supprimez la ligne httpRuntime et cela fonctionnera.
Fandango68
J'ai ajouté un avertissement rappelant aux utilisateurs de valider manuellement l'entrée lorsque la validation est désactivée.
Carter Medlin
72

Les réponses précédentes sont excellentes, mais personne n'a dit comment exclure un seul champ de la validation pour les injections HTML / JavaScript. Je ne connais pas les versions précédentes, mais dans MVC3 Beta, vous pouvez le faire:

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

Cela valide toujours tous les champs sauf celui exclu. La bonne chose à ce sujet est que vos attributs de validation valident toujours le champ, mais vous n'avez tout simplement pas les exceptions «Une valeur Request.Form potentiellement dangereuse a été détectée par le client».

Je l'ai utilisé pour valider une expression régulière. J'ai créé mon propre ValidationAttribute pour voir si l'expression régulière est valide ou non. Comme les expressions régulières peuvent contenir quelque chose qui ressemble à un script, j'ai appliqué le code ci-dessus - l'expression régulière est toujours vérifiée si elle est valide ou non, mais pas si elle contient des scripts ou du HTML.

gligoran
la source
10
Malheureusement, il semble que la fonction d'exclusion ait été supprimée de MVC 3 RTW :(
Matt Greer
2
Il n'était pas non plus inclus dans MVC 4
wilsjd
9
Utilisez-le [AllowHtml]sur les propriétés du modèle plutôt que [ValidateInput]sur l'action pour obtenir le même résultat final.
Mrchief
2
@Christof Notez que ma réponse a 5 ans. Je n'ai pas rencontré ce problème depuis très longtemps, donc il pourrait y avoir de bien meilleures façons de le résoudre. En ce qui concerne ces deux options, je pense que cela dépend de votre situation. Vous exposez peut-être ce modèle dans plusieurs actions et, à certains endroits, le HTML est autorisé ou non. Dans un tel cas, ce [AllowHtml]n'est pas une option. Je recommande de consulter cet article: weblogs.asp.net/imranbaloch/… , mais il est également un peu ancien et peut-être obsolète.
gligoran
1
Il existe toujours un moyen d'exclure des paramètres de méthode particuliers de la validation, consultez ma réponse ici: stackoverflow.com/a/50796666/56621
Alex
51

Dans ASP.NET MVC, vous devez définir requestValidationMode = "2.0" et validateRequest = "false" dans web.config, et appliquer un attribut ValidateInput à l'action de votre contrôleur:

<httpRuntime requestValidationMode="2.0"/>

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

et

[Post, ValidateInput(false)]
public ActionResult Edit(string message) {
    ...
}
ranthonissen
la source
2
Pour moi, ce validateRequest="false"n'était pas nécessaire, seulementrequestValidationMode="2.0"
tom redfern
requestValidationMode = "2.0" génère toujours l'erreur avec les données encodées en HTML. Aucune solution, sauf pour coder en base64 tout, puis envoyez-le.
MC9000
48

Vous pouvez encoder du contenu de zone de texte en HTML , mais malheureusement cela n'empêchera pas l'exception de se produire. D'après mon expérience, il n'y a pas moyen de contourner le problème et vous devez désactiver la validation des pages. En faisant cela, vous dites: "Je serai prudent, je le promets."

Pavel Chuchuva
la source
43

Pour MVC, ignorez la validation des entrées en ajoutant

[ValidateInput (false)]

au-dessus de chaque action dans le contrôleur.

A.Dara
la source
Cela ne semble pas fonctionner dans le cas où il arrive à la méthode du contrôleur via une route configurée.
PandaWood
En fait, l'explication technique est que cela ne fonctionne que lorsque le caractère incriminé est dans la "chaîne de requête" ... s'il se trouve dans le chemin de la demande, l'attribut de validation ne fonctionne pas
PandaWood
42

Vous pouvez intercepter cette erreur dans Global.asax. Je veux toujours valider, mais afficher un message approprié. Sur le blog ci-dessous, un échantillon comme celui-ci était disponible.

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

La redirection vers une autre page semble également être une réponse raisonnable à l'exception.

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

BenMaddox
la source
40

La réponse à cette question est simple:

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

Cela désactiverait la validation de la demande particulière.

flakomalo
la source
1
Applicable uniquement pour ASP.NET 4.5 (et, vraisemblablement, tout ce qui viendra après). Pre 4.5 ne le prend pas en charge.
Beska
3
J'aimerais pouvoir remonter de cette façon. J'utilise .NET 4.5 et c'est exactement ce dont j'avais besoin car je n'utilise pas MVC et je ne peux pas changer le web.config.
Chris Gillum
1
Oui, mais si vous utilisez .Net 2? Certains d'entre nous n'ont pas le choix
Fandango68
cela obtient des paramètres POST ou GET?
max4ever
Voulez-vous dire que cela empêche une exception qui a déjà été levée? Ou .net 4.5 retarde-t-il l'exception et la validation jusqu'à ce que les données soient réellement lues à partir du Request?
ebyrob
34

Veuillez garder à l'esprit que certains contrôles .NET encoderont automatiquement en HTML la sortie. Par exemple, la définition de la propriété .Text sur un contrôle TextBox le codera automatiquement. Cela signifie spécifiquement la conversion <en &lt;, >en &gt;et &en &amp;. Alors méfiez-vous de faire cela ...

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

Cependant, la propriété .Text pour HyperLink, Literal et Label ne codera pas les choses en HTML, encapsulant donc Server.HtmlEncode (); autour de tout ce qui est défini sur ces propriétés est un must si vous voulez empêcher <script> window.location = "http://www.google.com"; </script>d'être sorti dans votre page et exécuté par la suite.

Faites un peu d'expérimentation pour voir ce qui est encodé et ce qui ne l'est pas.

Peter Mortensen
la source
29

Dans le fichier web.config, dans les balises, insérez l'élément httpRuntime avec l'attribut requestValidationMode = "2.0". Ajoutez également l'attribut validateRequest = "false" dans l'élément pages.

Exemple:

<configuration>
  <system.web>
   <httpRuntime requestValidationMode="2.0" />
  </system.web>
  <pages validateRequest="false">
  </pages>
</configuration>
Mahdi jokar
la source
1
Pour moi, validateRequest = "false" n'était pas nécessaire, seulement requestValidationMode = "2.0"
tom redfern
3
La section "pages" doit se trouver dans la section "system.web".
Carter Medlin
réponse dangereuse, encore une fois.
MC9000
J'avais besoin des deux. Merci
Jack
23

Si vous ne souhaitez pas désactiver ValidateRequest, vous devez implémenter une fonction JavaScript afin d'éviter l'exception. Ce n'est pas la meilleure option, mais cela fonctionne.

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

Ensuite, dans le code derrière, sur l'événement PageLoad, ajoutez l'attribut à votre contrôle avec le code suivant:

Me.TextBox1.Attributes.Add("OnKeyPress", "return AlphanumericValidation(event);")
Peter Mortensen
la source
4
Cela laissera toujours l'application vulnérable aux demandes POST composées. Un utilisateur normal rencontrera des problèmes pour saisir des caractères tels que:: ou des guillemets, mais un pirate informatique normal n'aura aucun problème à POSTER des données incorrectes sur le serveur. Je vode ce waaay.
Radu094
13
@ Radu094: Cette solution vous permet de garder ValidateRequest = true, ce qui signifie que les pirates vont toujours frapper ce mur. Votez UP, car cela vous rend moins vulnérable que de désactiver ValidateRequest.
jbehren
21

Il semble que personne n'ait encore mentionné ce qui suit, mais cela résout le problème pour moi. Et avant que quelqu'un ne dise oui, c'est Visual Basic ... beurk.

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

Je ne sais pas s'il y a des inconvénients, mais pour moi, cela a fonctionné de manière incroyable.

Piercy
la source
Fonctionne pour les formulaires Web c # ou VB
TheAlbear
19

Une autre solution est:

protected void Application_Start()
{
    ...
    RequestValidator.Current = new MyRequestValidator();
}

public class MyRequestValidator: RequestValidator
{
    protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
    {
        bool result = base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);

        if (!result)
        {
            // Write your validation here
            if (requestValidationSource == RequestValidationSource.Form ||
                requestValidationSource == RequestValidationSource.QueryString)

                return true; // Suppress error message
        }
        return result;
    }
}
Sel
la source
Agréable! N'était pas au courant de la possibilité de remplacer le validateur de demande. Au lieu de simplement dire "ok" comme vous, j'ai étendu cette idée pour ne pas valider les champs qui se terminent par "_NoValidation" comme leur nom. Code ci-dessous.
Walden Leverich
Walden Leverich, pour ce faire, voir l'attribution [AllowHtml]
Sel
Sel, oui dans un environnement MVC qui fonctionnerait. Mais dans une application webforms, je n'ai pas de modèle pour le faire. :-)
Walden Leverich
15

Si vous utilisez Framework 4.0, l'entrée dans le web.config (<pages validateRequest = "false" />)

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

Si vous utilisez le framework 4.5, l'entrée dans le web.config (requestValidationMode = "2.0")

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

Si vous ne voulez qu'une seule page, dans votre fichier aspx, vous devez mettre la première ligne comme ceci:

<%@ Page EnableEventValidation="false" %>

si vous avez déjà quelque chose comme <% @ Page, ajoutez simplement le reste => EnableEventValidation="false" %>

Je recommande de ne pas le faire.

Durgesh Pandey
la source
13

Dans ASP.NET, vous pouvez intercepter l'exception et faire quelque chose, comme afficher un message convivial ou rediriger vers une autre page ... Il existe également une possibilité que vous puissiez gérer la validation par vous-même ...

Afficher un message convivial:

protected override void OnError(EventArgs e)
{
    base.OnError(e);
    var ex = Server.GetLastError().GetBaseException();
    if (ex is System.Web.HttpRequestValidationException)
    {
        Response.Clear();
        Response.Write("Invalid characters."); //  Response.Write(HttpUtility.HtmlEncode(ex.Message));
        Response.StatusCode = 200;
        Response.End();
    }
}
Jaider
la source
13

Je suppose que vous pourriez le faire dans un module; mais cela laisse ouvertes quelques questions; que faire si vous souhaitez enregistrer l'entrée dans une base de données? Du coup, parce que vous enregistrez des données encodées dans la base de données, vous finissez par faire confiance à ses entrées, ce qui est probablement une mauvaise idée. Idéalement, vous stockez des données brutes non codées dans la base de données et les encodez à chaque fois.

Désactiver la protection au niveau de chaque page, puis encoder à chaque fois est une meilleure option.

Plutôt que d'utiliser Server.HtmlEncode, vous devriez regarder la bibliothèque Anti-XSS plus récente et plus complète de l'équipe Microsoft ACE.

Blowdart
la source
12

Cause

ASP.NET par défaut valide tous les contrôles d'entrée pour les contenus potentiellement dangereux qui peuvent conduire à des scripts intersite (XSS) et des injections SQL . Ainsi, il interdit un tel contenu en lançant l'exception ci-dessus. Par défaut, il est recommandé d'autoriser cette vérification à chaque publication.

Solution

À de nombreuses reprises, vous devez soumettre du contenu HTML à votre page via Rich TextBoxes ou Rich Text Editors. Dans ce cas, vous pouvez éviter cette exception en définissant la balise ValidateRequest dans la @Pagedirective sur false.

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

Cela désactivera la validation des demandes pour la page sur laquelle vous avez défini l'indicateur ValidateRequest sur false. Si vous souhaitez désactiver cela, vérifiez tout au long de votre application Web; vous devrez le définir sur false dans votre section web.config <system.web>

<pages validateRequest ="false" />

Pour les frameworks .NET 4.0 ou supérieur, vous devrez également ajouter la ligne suivante dans la section <system.web> pour que le travail ci-dessus fonctionne.

<httpRuntime requestValidationMode = "2.0" />

C'est ça. J'espère que cela vous aidera à vous débarrasser du problème ci-dessus.

Référence par: ASP.Net Erreur: une valeur Request.Form potentiellement dangereuse a été détectée par le client

vakeel
la source
10

J'ai trouvé une solution qui utilise JavaScript pour encoder les données, qui est décodée en .NET (et ne nécessite pas jQuery).

  • Faites de la zone de texte un élément HTML (comme une zone de texte) au lieu d'un élément ASP.
  • Ajoutez un champ masqué.
  • Ajoutez la fonction JavaScript suivante à votre en-tête.

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

Dans votre zone de texte, incluez un onchange qui appelle boo ():

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

Enfin, dans .NET, utilisez

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

Je suis conscient que c'est à sens unique - si vous avez besoin de deux sens, vous devrez faire preuve de créativité, mais cela fournit une solution si vous ne pouvez pas modifier le web.config

Voici un exemple que j'ai (MC9000) trouvé et utilisé 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
    });


});

Et le balisage:

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

Cela fonctionne très bien. Si un pirate tente de publier en contournant JavaScript, il verra simplement l'erreur. Vous pouvez également enregistrer toutes ces données encodées dans une base de données, puis les échapper (côté serveur) et analyser et rechercher les attaques avant de les afficher ailleurs.

Jason Shuler
la source
C'est une bonne solution. C'est un moyen manuel approprié de le contrôler vous-même et de ne pas invalider l'intégralité du site Web ou de la page
Fandango68
Assurez-vous d'utiliser un balisage HTML, pas un contrôle ASP.Net (c'est-à-dire pas de runat = "serveur") pour la zone de texte, puis utilisez le contrôle caché ASP.Net pour le caché. C'est la meilleure solution que j'ai vue sans compromettre quoi que ce soit. Naturellement, vous voulez analyser vos données pour XSS, SQL Injection côté serveur, mais au moins vous pouvez publier HTML
MC9000
escape(...)peut prendre beaucoup de temps. Dans mon cas, le balisage était un fichier XML entier (2 Mo). Vous pourriez demander: "Pourquoi ne pas simplement utiliser <input type="file"...et ... je suis d'accord avec vous :)
The Red Pea
10

Les autres solutions ici sont agréables, mais c'est un peu pénible à l'arrière d'avoir à appliquer [AllowHtml] à chaque propriété de modèle, surtout si vous avez plus de 100 modèles sur un site de taille décente.

Si comme moi, vous souhaitez désactiver cette fonctionnalité (à mon humble avis) hors du site, vous pouvez remplacer la méthode Execute () dans votre contrôleur de base (si vous n'avez pas déjà de contrôleur de base, je vous suggère d'en créer un, ils peuvent être assez utile pour appliquer des fonctionnalités communes).

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

Assurez-vous simplement que vous encodez HTML tout ce qui est pompé vers les vues provenant des entrées utilisateur (c'est de toute façon le comportement par défaut dans ASP.NET MVC 3 avec Razor, donc à moins que pour une raison bizarre vous n'utilisez Html.Raw () vous ne devrait pas nécessiter cette fonctionnalité.

magritte
la source
9

J'obtenais aussi cette erreur.

Dans mon cas, un utilisateur a entré un caractère accentué ádans un nom de rôle (concernant le fournisseur d'appartenance ASP.NET).

Je passe le nom du rôle à une méthode pour accorder des utilisateurs à ce rôle et la $.ajaxdemande de publication échouait lamentablement ...

J'ai fait cela pour résoudre le problème:

Au lieu de

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

Faites ceci

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

@Html.Raw a fait l'affaire.

J'obtenais le nom de rôle en tant que valeur HTML roleName="Cadastro b&#225;s". Cette valeur avec l'entité HTML &#225;était bloquée par ASP.NET MVC. Maintenant, j'obtiens la roleNamevaleur du paramètre telle qu'elle devrait être: roleName="Cadastro Básico"et le moteur ASP.NET MVC ne bloquera plus la demande.

Leniel Maccaferri
la source
9

Désactiver la validation de page si vous avez vraiment besoin des caractères spéciaux comme, >,, <, etc. Assurez -vous ensuite que lorsque l'entrée utilisateur est affiché, les données HTML codées.

Il existe une vulnérabilité de sécurité liée à la validation de la page, elle peut donc être contournée. De plus, la validation de la page ne doit pas être uniquement basée sur.

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

woany
la source
Le lien est rompu.
Peter Mortensen
7

Vous pouvez également utiliser la fonction d' échappement (chaîne) de JavaScript pour remplacer les caractères spéciaux. Ensuite, côté serveur, utilisez Serveur. URLDecode (chaîne) pour le réactiver .

De cette façon, vous n'avez pas à désactiver la validation d'entrée et il sera plus clair pour les autres programmeurs que la chaîne peut avoir du contenu HTML.

Trisped
la source
7

J'ai fini par utiliser JavaScript avant chaque publication pour vérifier les caractères que vous ne vouliez pas, tels que:

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

Certes, ma page est principalement une entrée de données, et il y a très peu d'éléments qui font des publications, mais au moins leurs données sont conservées.

Ryan
la source
Il devrait y avoir de gros crochets au lieu de petits crochets. Comme `if (tbs [i] .type == 'text') {` à la place de `if (tbs (i) .type == 'text') {`
Shilpa Soni
5

Vous pouvez utiliser quelque chose comme:

var nvc = Request.Unvalidated().Form;

Plus tard, cela nvc["yourKey"]devrait fonctionner.

Ady Levy
la source
Merci, votre réponse m'a fait gagner beaucoup de temps
habib
4

Tant que ce ne sont que des caractères "<" et ">" (et non les guillemets eux-mêmes) et que vous les utilisez dans un contexte comme <input value = " this " />, vous êtes en sécurité (alors que pour <textarea > celui-ci </textarea> vous seriez bien sûr vulnérable). Cela peut simplifier votre situation, mais pour n'importe quoi de plus, utilisez l'une des autres solutions publiées.

Paweł Hajdan
la source
4

Si vous cherchez simplement à dire à vos utilisateurs que <et> ne doivent pas être utilisés MAIS, vous ne voulez pas que le formulaire entier soit traité / publié à l'avance (et que vous perdiez toutes les entrées) à l'avance. Ne pourriez-vous pas simplement mettre un validateur sur le terrain pour filtrer ces personnages (et peut-être d'autres potentiellement dangereux)?

Captain Toad
la source
post dit "validateur" s'il vous plaît
mxmissile
4

Aucune des suggestions n'a fonctionné pour moi. Je ne voulais pas désactiver cette fonctionnalité pour tout le site Web de toute façon parce que 99% du temps, je ne veux pas que mes utilisateurs placent du HTML sur des formulaires Web. Je viens de créer ma propre méthode de contournement puisque je suis le seul à utiliser cette application particulière. Je convertis l'entrée en HTML dans le code derrière et l'insère dans ma base de données.

Mike S.
la source