23 votes

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

J'ai un formulaire avec l'éditeur wmd dessus. La zone de texte de saisie est rendue à l'aide de :

<%: Html.TextAreaFor(t => t.NewsBody, new{@class="wmd-panel", id="wmd-input"}) %>

Chaque fois que je soumets le formulaire, j'obtiens A potentially dangerous Request.Form value was detected from the client

J'ai essayé de définir [ValidateInput(false)] sur la méthode d'action, j'ai essayé d'ajouter <httpRuntime requestValidationMode="2.0" /> au web.config et j'ai essayé validateRequest="false" dans la directive pages dans web.config mais cela se produit toujours.

Des idées ?

Modifier

Méthode d'action :

 [ILFFAuthorize(Roles = "Admin")] // this is a custom auth attrobite
        [HttpPost]
        [ValidateInput(false)]
        public ActionResult AddNews(FormCollection col){

        //public ActionResult AddNews(News news)
        //{
            if (ModelState.IsValid)
            {
                News news = new News();
                news.NewsDate = DateTime.Now;
                news.NewsPosterId = 0;

                news.NewsTitle = col["NewsTitle"];
                news.NewsBody = col["NewsBody"];
                newsRepository.Add(news);
                newsRepository.Save();

                return RedirectToAction("Index", "Home");
            }
            else
            {
                return View();
            }
        }

0voto

Deividas Points 34

J'ai essayé de trouver une solution à ce problème toute la journée.
La désactivation de la validation n'était pas une option.
L'ajout de allowHtml n'était pas non plus une option, car par la spécification msdn :
AllowHtmlAttribute permet à une demande d'inclure un balisage HTML pendant la liaison du modèle en ignorant la validation de la demande pour la propriété. source

De plus, il y a beaucoup de propriétés avec des attributs de chaîne dans un projet qui devraient être validées si la validation par défaut est définie sur false.

Solution :

J'ai créé une classe CustomRequestValidation :

public class CustomRequestValidation : System.Web.Util.RequestValidator
{
    protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
    {
        validationFailureIndex = -1;
        if (requestValidationSource == RequestValidationSource.RawUrl)
            return true;

        if (requestValidationSource == RequestValidationSource.Form)
        {
            var isValid = base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);
            if (!isValid)
            {
                validationFailureIndex = -1;
                return true;
            }
        }

        return base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);
    }
}

ce qu'il fait, c'est qu'il saute simplement la RequestValidation dans le but d'atteindre l'état du modèle.

Ensuite, j'ai remplacé le modèle de classeur par défaut :

public class CustomModelBinder : DefaultModelBinder
{

    protected override bool OnPropertyValidating(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, object value)
    {
        if (value != null)
        {
            if (propertyDescriptor.PropertyType == typeof(string))
            {
                string val = value.ToString();
                int validationIndex;
                var isValid = new System.Web.Util.RequestValidator().InvokeIsValidRequestString(controllerContext.HttpContext.ApplicationInstance.Context, val, RequestValidationSource.Form, null, out validationIndex);
                if (!isValid && !propertyDescriptor.Attributes.OfType<AllowHtmlAttribute>().IsAny())
                {
                    var key = CreateSubPropertyName(bindingContext.ModelName, propertyDescriptor.Name);
                    bindingContext.ModelState.AddModelError(key, ErrorConstants.SpecialCharacters);
                }
            }
        }

        return base.OnPropertyValidating(controllerContext, bindingContext, propertyDescriptor, value);
    }
}

Maintenant, ici, nous faisons toute la validation. Dans le binder du modèle, j'appelle la méthode par défaut .Net IsValidRequestString et je vérifie si AllowHtml a été défini et je définis l'état du modèle en conséquence. Cela me donne le contrôle sur les données et je peux retourner à la page et remplir le formulaire avec les données précédemment saisies sans déclencher de scripts insérés. J'utilise des modèles fortement typés.

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