1574 votes

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

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

Je ne veux pas entrer dans la discussion sur la pertinence de lancer une exception ou de faire planter toute une application web parce que quelqu'un a saisi un caractère dans une zone de texte, mais je recherche une manière élégante de gérer cela.

Attraper l'exception et afficher

Une erreur s'est produite, veuillez revenir en arrière et retaper tout votre formulaire à nouveau, mais cette fois ne pas utiliser <

ne me semble pas assez professionnel.

Désactiver la validation des posts (validateRequest="false") évitera certainement cette erreur, mais laissera la page vulnérable à un certain nombre d'attaques.

Idéalement : lorsqu'un post back se produit contenant des caractères HTML restreints, cette valeur postée dans la collection Form sera automatiquement encodée en HTML. Donc, la propriété .Text de ma zone de texte sera quelque chose & lt; html & gt;

Y a-t-il un moyen de faire cela à partir d'un gestionnaire?

76 votes

Notez que vous pouvez obtenir cette erreur si vous avez des noms d'entités HTML (&) ou des nombres d'entités (') dans votre entrée également.

30 votes

Eh bien, étant donné que c'est ma question, je pense pouvoir définir ce que le point est réellement: faire crasher tout un processus d'application et renvoyer un message d'erreur générique simplement parce que quelqu'un a tapé un '<' est exagéré. Surtout sachant que la plupart des gens vont simplement mettre 'validateRequest=false' pour s'en débarrasser, réouvrant ainsi la vulnérabilité

10 votes

@DrewNoakes : les noms d'entité (&) ne semblent pas poser de problème selon mes tests (effectués en .Net 4.0), bien que les numéros d'entité (') échouent à la validation (comme vous l'avez dit). Si vous désassemblez la méthode System.Web.CrossSiteScriptingValidation.IsDangerousString en utilisant .Net Reflector, vous verrez que le code recherche spécifiquement des balises HTML (commençant par <) et des numéros d'entité (commençant par &#)

1140voto

JacquesB Points 19878

Je pense que vous l'abordez de la mauvaise manière en essayant d'encoder toutes les données postées.

Notez qu'un "<" pourrait é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. Il n'est dangereux que dans un contexte spécifique : lors de l'écriture de chaînes qui n'ont pas été encodées pour la sortie HTML (à cause de XSS).

Dans d'autres contextes, différentes sous-chaînes peuvent être 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 de l'apostrophe, en revanche, 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 par un formulaire ou lu à partir d'un champ de base de données.

En conclusion : vous ne pouvez pas filtrer une entrée aléatoire pour des caractères dangereux, car n'importe quel caractère peut être dangereux dans les bonnes circonstances. Vous devez encoder au point où certains caractères spécifiques peuvent devenir dangereux car ils passent dans une sous-langue différente où ils ont une signification particulière. Lorsque vous écrivez une chaîne en HTML, vous devez encoder les caractères ayant une signification spéciale en HTML, en utilisant Server.HtmlEncode. Si vous transmettez une chaîne à une instruction SQL dynamique, vous devez encoder différents caractères (ou mieux, laissez le framework le faire pour vous en utilisant des requêtes préparées ou autre chose).

Lorsque vous êtes sûr d'encoder en HTML partout où vous transmettez des chaînes en HTML, définissez ValidateRequest="false" dans la directive <%@ Page ... %> de votre(s) fichier(s) .aspx.

Dans .NET 4, il peut être nécessaire de faire un peu plus. Parfois, il est également nécessaire d'ajouter à web.config (référence).

0 votes

@Hightechrider merci pour ce lien. La simple configuration validateRequest="false" ne fonctionne pas pour une vue dans ASP.Net MVC @olavk - Bien. Joel a pris le temps de commenter votre réponse.

80 votes

Aux retardataires : validateRequest="false" va dans la directive Page (première ligne de votre fichier .aspx)

63 votes

Conseil : Placez dans une balise location pour éviter de désactiver la protection utile offerte par la validation pour le reste de votre site.

531voto

Zack Peterson Points 19350

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

Exemple en C# :

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

Exemple en Visual Basic :

 _
Fonction Edit(collection As FormCollection) As ActionResult
    ...
End Function

0 votes

Le problème peut survenir lorsqu'il est nécessaire sur une seule page de toute l'application.

3 votes

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 du contrôleur.

0 votes

@Zack Merci pour la solution. D'autre part, je me demande si [AllowHtml] est meilleur que ValidateInput(false), car [AllowHtml] est défini une fois pour une propriété, c'est-à-dire un champ d'éditeur, et chaque fois qu'il est utilisé, il n'est pas nécessaire de l'utiliser pour plusieurs actions. Qu'en pensez-vous?

440voto

Anthony Johnston Points 3133

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

Cela permet à une requête d'inclure des balises HTML lors de la liaison du modèle en ignorant la validation de la requête pour la propriété.

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

14 votes

Beaucoup mieux de le faire de manière déclarative que dans le contrôleur!

0 votes

Est-ce que cela a disparu en MVC 4?

0 votes

Il semble que cela ne se trouve que dans le cadre DotNet 4.0. msdn.microsoft.com/fr-fr/library/… Et pourquoi ???

220voto

JordanC Points 2433

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


Sur .NET 2.0, la validation des requêtes ne s'appliquait qu'aux requêtes aspx. Sur .NET 4.0, cela a été étendu pour inclure toutes les requêtes. Vous pouvez revenir à ne réaliser la validation XSS que lors du traitement des fichiers .aspx en spécifiant :

requestValidationMode="2.0"

Vous pouvez désactiver la validation des requêtes entièrement en spécifiant :

validateRequest="false"

31 votes

À l'intérieur des balises .

9 votes

J'ai mis cela dans le web.config, mais je reçois toujours l'erreur "Une valeur Request.Form potentiellement dangereuse "

20 votes

Il semblerait que fonctionne uniquement lorsque le framework 2.0 est installé sur la machine. Et si le framework 2.0 n'est pas du tout installé mais que seul le framework 4.0 est installé ?

121voto

Carter Points 3877

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

...

...

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

Vous devez toujours valider l'entrée de manière programmatique sur les pages où la validation de la requête est désactivée.

0 votes

Plus d'informations sur requestValidationMode=2|4 ici: msdn.microsoft.com/en-us/library/…

0 votes

Malheureusement, cela ne fonctionnera pas avec ASP.net 2.0 tel quel. Supprimez la ligne httpRuntime et cela fonctionnera.

0 votes

J'ai ajouté un avertissement rappelant aux gens de valider manuellement les entrées lorsque la validation est désactivée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X