Potentiellement dangereuse Demande.La valeur du formulaire a été détectée par le client
chaque fois qu'un utilisateur poste quelque chose contenant <
ou >
dans une page de mon application web, Je reçois cette exception jeté.
Je ne veux pas entrer dans la discussion sur l'opportunité de lancer une exception ou de planter toute une application web parce que quelqu'un a entré un personnage dans une zone de texte, mais je cherche une façon élégante de gérer cela.
recouvrement de l'exception et en montrant
une erreur s'est produite s'il vous plaît retournez et tapez à nouveau votre formulaire entier, mais cette fois s'il vous plaît ne pas utiliser <
ne me semble pas assez professionnel.
désactiver la post validation ( validateRequest="false"
) permettra certainement d'éviter cette erreur, mais il laissera la page vulnérable à un certain nombre d'attaques.
idéalement: Lorsqu'un post back contient des caractères HTML restreints, cette valeur affichée dans la forme collection sera automatiquement codée HTML.
Ainsi, la propriété .Text
de ma boîte de texte sera something & lt; html & gt;
y a-t-il un moyen pour que je puisse faire ça d'un handler?
30 réponses
je pense que vous l'attaquez du mauvais angle en essayant de coder toutes les données postées.
notez qu'un" <
" peut aussi provenir d'autres sources externes, comme un champ de base de données, une configuration, un fichier, un feed, etc.
en outre, <
" 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 en 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. L'apostrophe sur l'autre main est dangereux lors de l'interpolation des chaînes dans les requêtes SQL, mais parfaitement sûr si c'est une partie d'un nom à partir d'un formulaire ou lire à partir d'un champ de base de données.
la ligne de fond est: vous ne pouvez pas filtrer les entrées aléatoires pour les caractères dangereux, parce que n'importe quel le caractère peut être dangereux dans les bonnes circonstances. Vous devez coder au point où certains caractères spécifiques peuvent devenir dangereux parce qu'ils se croisent dans un sous-langage différent où ils ont une signification particulière. Lorsque vous écrivez une chaîne de caractères en HTML, vous devez encoder les caractères qui ont une signification spéciale en HTML, en utilisant le serveur.HtmlEncode. Si vous passez une chaîne à une déclaration SQL dynamique, vous devriez encoder des caractères différents (ou mieux, laissez le framework le faire pour vous en utilisant prepared déclarations ou similaires)..
Quand vous êtes sûr de coder en HTML les données partout où vous passez des chaînes au format HTML, puis réglez validateRequest="false"
dans le <%@ Page ... %>
directive dans votre .aspx
fichier(s).
dans .NET 4 vous pourriez avoir besoin de faire un peu plus. Parfois, il est nécessaire d'ajouter <httpRuntime requestValidationMode="2.0" />
au web.config ( référence ).
il y a une solution différente à cette erreur si vous utilisez ASP.NET MVC:
- ASP.NET MVC-pages validateRequest=false ne fonctionne pas?
- pourquoi ValidateInput(False) ne fonctionne-t-il pas?
- ASP.NET MVC RC1, VALIDATEINPUT, A POTENTIAL DANGEROUS REQUEST AND THE PITFALL
C# exemple:
[HttpPost, ValidateInput(false)]
public ActionResult Edit(FormCollection collection)
{
// ...
}
Visual Basic sample:
<AcceptVerbs(HttpVerbs.Post), ValidateInput(False)> _
Function Edit(ByVal collection As FormCollection) As ActionResult
...
End Function
In ASP.NET MVC (à partir de la version 3), vous pouvez ajouter l'attribut AllowHtml
à une propriété sur votre modèle.
il permet à une requête D'inclure un balisage HTML lors de la fixation du modèle en sautant la validation de la requête pour la propriété.
[AllowHtml]
public string Description { get; set; }
si vous êtes sur .NET 4.0 assurez-vous d'ajouter ceci dans votre web.config fichier à l'intérieur des <system.web>
tags:
<httpRuntime requestValidationMode="2.0" />
.NET 2.0, validation de la demande applique uniquement aux aspx
les demandes. Dans .NET 4.0, ce champ a été élargi pour inclure les demandes toutes les demandes . Vous pouvez revenir à seulement effectuer la validation XSS lors du traitement .aspx
en spécifiant:
requestValidationMode="2.0"
vous pouvez désactiver request valider entièrement en spécifiant:
validateRequest="false"
pour ASP.NET 4.0, vous pouvez autoriser le balisage comme entrée pour des pages spécifiques au lieu de l'ensemble du site en mettant tout dans un élément <location>
. Cela permettra de s'assurer que toutes vos autres pages sont en sécurité. Vous n'avez pas besoin de mettre ValidateRequest="false"
dans votre .aspx page.
<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 à l'intérieur de votre web.config, parce que vous pouvez voir au niveau du site quelles pages permettent le markup comme entrée.
Vous avez encore besoin de valider programmatiquement les entrées sur les pages où la validation de la requête est désactivée.
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 sais pas pour les versions précédentes, mais dans MVC3 Beta vous pouvez faire ceci:
[HttpPost, ValidateInput(true, Exclude = "YourFieldName")]
public virtual ActionResult Edit(int id, FormCollection collection)
{
...
}
ceci valide encore tous les champs sauf celui exclu. Ce qui est bien, c'est que vos attributs de validation valident toujours le champ, mais vous ne recevez pas la requête "a potentially dangerous Request.La valeur de la forme a été détectée à partir du client" des exceptions.
j'ai utilisé ceci pour valider une expression régulière. J'ai fait ma 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 encore vérifiée si elle est valide ou non, mais pas si elle contient des scripts ou du HTML.
In ASP.NET MVC vous devez définir requestValidationMode= "2.0"et validateRequest=" false " dans web.config, et d'appliquer une ValidateInput attribut à votre contrôleur de l'action:
<httpRuntime requestValidationMode="2.0"/>
<configuration>
<system.web>
<pages validateRequest="false" />
</system.web>
</configuration>
et
[Post, ValidateInput(false)]
public ActionResult Edit(string message) {
...
}
Vous pouvez codage HTML zone de texte de contenu, mais malheureusement ce ne sera pas cesser de l'exception de passe. D'après mon expérience, il n'y a pas de solution et vous devez désactiver la validation de la page. En faisant ça, tu dis: "je serai prudent, je te le promets."
pour MVC, ignorer la validation d'entrée en ajoutant
[ValidateInput(false)]
au-dessus de chaque Action dans le contrôleur.
vous pouvez attraper cette erreur dans Global.asax. J'en veux encore à 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();
}
}
rediriger vers une autre page semble aussi être une réponse raisonnable à l'exception.
http://www.romsteady.net/blog/2007/06/how-to-catch-httprequestvalidationexcep.html
s'il vous plaît garder à l'esprit que certains contrôles .NET sera automatiquement HTML encoder la sortie. Par exemple, le réglage de l' .La propriété Text sur un contrôle TextBox l'encodera automatiquement. Cela signifie spécifiquement la conversion de <
en <
, >
en >
et &
en &
. Donc, méfiez-vous de le faire...
myTextBox.Text = Server.HtmlEncode(myStringFromDatabase); // Pseudo code
Toutefois, l' .La propriété textuelle pour HyperLink, Literal et Label n'encodera pas les choses HTML, donc emballage Serveur.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 ensuite exécuté.
faire un peu d'expérimentation pour voir ce qui est encodé et ce qui ne l'est pas.
la réponse à cette question est simple:
var varname = Request.Unvalidated["parameter_name"];
ceci désactiverait la validation pour la requête particulière.
sur le web.fichier de configuration, 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>
si vous ne voulez pas désactiver ValidateRequest, vous devez implémenter une fonction JavaScript afin d'éviter l'exception. Ce n'est pas la meilleure option, mais il 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;
}
}
puis en 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);")
Il semble que personne n'a mentionné ci-dessous, mais il résout le problème pour moi. Et avant que quelqu'un dise oui, C'est visuel de base... 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é incroyable.
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;
}
}
In ASP.NET, vous pouvez attraper l'exception et faire quelque chose à ce sujet, comme l'affichage d'un message amical ou rediriger vers une autre page... Il est également possible que vous puissiez gérer vous-même la validation...
Afficher message amical:
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();
}
}
je suppose que vous pourriez le faire dans un module; mais qui laisse en suspens certaines questions; si vous souhaitez enregistrer l'entrée d'une base de données? Soudainement, parce que vous sauvegardez des données codées dans la base de données, vous finissez par faire confiance à la saisie de celui-ci 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 l'encodage à chaque fois.
désactiver la protection au niveau de la page et ensuite encoder à chaque fois est une meilleure option.
plutôt que l'utilisation du Serveur.HtmlEncode vous devriez regarder le plus récent, plus complet Bibliothèque Anti-XSS de L'équipe de Microsoft ACE.
si vous utilisez framework 4.0 puis l'entrée dans le web.config (
<configuration>
<system.web>
<pages validateRequest="false" />
</system.web>
</configuration>
si vous utilisez framework 4.5 alors 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 voulez pour une seule page alors, 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 alors ajoutez juste le reste => EnableEventValidation="false"
% >
je recommande de ne pas le faire.
les autres solutions ici sont belles, mais c'est un peu une douleur royale à l'arrière de devoir 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 voulez tourner cette fonctionnalité (IMHO assez inutile) hors site vous pouvez outrepasser la méthode Execute () dans votre contrôleur de base (si vous n'avez pas déjà un contrôleur de base je vous suggère d'en faire un, ils peuvent être assez utiles pour appliquer fonctionnalité commune).
protected override void Execute(RequestContext requestContext)
{
// Disable requestion validation (security) across the whole site
ValidateRequest = false;
base.Execute(requestContext);
}
assurez-vous simplement que vous êtes HTML encodant tout ce qui est pompé vers les vues qui proviennent de l'entrée de l'utilisateur (c'est le comportement par défaut dans ASP.NET MVC 3 avec Razor de toute façon, donc à moins que pour une raison bizarre vous utilisez Html.Raw() vous ne devriez pas avoir besoin de cette fonctionnalité.
j'ai eu cette erreur aussi.
dans mon cas, un utilisateur a entré un caractère accentué á
dans un nom de rôle (concernant ASP.NET fournisseur d'adhésion).
je passe le nom du rôle à une méthode pour accorder les utilisateurs à ce rôle et la demande de poste $.ajax
a échoué lamentablement...
j'ai fait ceci 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 du rôle comme valeur HTML roleName="Cadastro bás"
. Cette valeur avec l'entité HTML á
était bloquée par ASP.NET MVC. Maintenant j'obtiens la valeur du paramètre roleName
comme elle devrait être: roleName="Cadastro Básico"
et ASP.NET le moteur MVC ne bloque plus la demande.
Cause
ASP.NET par défaut valide tous les contrôles d'entrée pour les contenus potentiellement dangereux qui peuvent conduire à Cross-site scripting (XSS) et SQL injections . Il rejette donc un tel contenu en jetant l'exception ci-dessus. Par défaut, il est recommandé de laisser cette case pour arriver sur chaque publication.
Solution
à de nombreuses occasions, vous devez soumettre du contenu HTML à votre page à travers des boîtes de texte riches ou des éditeurs de texte riches. Dans ce cas, vous pouvez éviter cette exception en définissant la balise ValidateRequest dans la directive @Page
à false.
<%@ Page Language="C#" AutoEventWireup="true" ValidateRequest = "false" %>
ceci désactivera la validation des requêtes pour la page où vous avez placé le drapeau ValidateRequest à false. Si vous voulez désactiver cela, vérifiez tout au long de votre application web; vous aurez besoin de mettre à false dans votre Web.config
<pages validateRequest ="false" />
pour les frameworks .net 4.0 ou supérieurs, vous devrez aussi ajouter la ligne suivante dans le
<httpRuntime requestValidationMode = "2.0" />
C'est ça. J'espère que cela vous aide à se débarrasser du problème ci-dessus.
référence par: ASP.Net erreur: une requête potentiellement dangereuse.La valeur du formulaire a été détectée chez le client
désactiver la validation de la page si vous avez vraiment besoin des caractères spéciaux comme, >
, , <
, etc. Ensuite, assurez-vous que lorsque l'entrée de l'utilisateur est affichée, les données sont codées HTML.
il y a une vulnérabilité de sécurité avec la validation de la page, donc elle peut être contournée. De plus, la validation de la page ne devrait pas être uniquement fiable.
voir: http://www.procheckup.com/PDFs/bypassing-dot-NET-ValidateRequest.pdf
j'ai trouvé une solution qui utilise JavaScript pour coder les données, qui est décodé dans .NET (et ne nécessite pas jQuery).
- faites de la boîte de texte un élément HTML (comme textarea) au lieu d'un élément ASP.
- Ajouter un champ caché.
-
ajouter la fonction JavaScript suivante à votre en-tête.
fonction boo() { targetText = document.getElementById ("HiddenField1"); sourceText = document.getElementById("bloc utilisateur"); targetText.valeur = escape (sourceText.innerText); }
dans votre textarea, incluez un onchange qui appelle boo ():
<textarea id="userbox" onchange="boo();"></textarea>
enfin, dans .NET, utiliser
string val = Server.UrlDecode(HiddenField1.Value);
je suis conscient que c'est à Sens Unique-si vous avez besoin de deux sens, vous devrez être créatif, mais cela fournit une solution si vous ne pouvez pas éditer le web.config
voici un exemple I (MC9000) est venu avec et utiliser 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 markup:
<asp:HiddenField ID="hidHTML" runat="server" />
<textarea id="txtHTML"></textarea>
<asp:Button ID="btnMyPostbackButton" runat="server" Text="Post Form" />
ça marche très bien. Si un pirate essaie de poster en contournant JavaScript, ils verront juste l'erreur. Vous pouvez enregistrer toutes ces données encodées dans une base de données, puis les désassembler (côté serveur), et analyser et vérifier les attaques avant de les afficher ailleurs.
vous pouvez également utiliser la fonction escape(string) de JavaScript pour remplacer les caractères spéciaux. Ensuite, Côté Serveur utiliser le serveur. URLDecode(string) pour revenir en arrière.
de cette façon, vous n'avez pas à désactiver la validation des entrées et il sera plus clair pour les autres programmeurs que la chaîne peut avoir du contenu HTML.
j'ai fini par utiliser JavaScript avant chaque postback 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;
}
étant donné que ma page est surtout une saisie de données, et qu'il y a très peu d'éléments qui font des envois postaux, mais au moins leurs données sont conservées.
aussi longtemps que ce sont des caractères seulement " < " et " > " (et pas la double citation elle-même) et vous les utilisez dans un contexte comme
si vous cherchez juste à dire à vos utilisateurs que < et > ne doivent pas être utilisés, mais que vous ne voulez pas que le formulaire entier soit traité/posté en arrière (et perdre toutes les entrées) avant-main, ne pourriez-vous pas simplement mettre un validateur autour du champ pour filtrer ces caractères (et peut-être d'autres potentiellement dangereux)?
aucune des suggestions n'a fonctionné pour moi. Je ne voulais pas désactiver cette fonctionnalité pour l'ensemble du site Web de toute façon parce que 99% du temps je ne veux pas que mes utilisateurs placent HTML sur les formulaires web. Je viens de créer mon propre travail autour de la méthode 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.
vous pouvez utiliser quelque chose comme:
var nvc = Request.Unvalidated().Form;
plus tard, nvc["yourKey"]
devrait fonctionner.