31 votes

Le paramètre ValidateRequest d'une page peut-il être remplacé ?

J'ai un formulaire ASP.NET MVC qui peut (et c'est généralement le cas) soumettre une réponse qui déclencherait l'erreur "A potentially dangerous Request.Form value was detected form the client".

Pour essayer de contourner ce problème, j'ai placé une directive ValidateRequest="false" dans la page.

Seul problème : je reçois toujours l'erreur !

Tout allait bien jusqu'à ce que je fasse la mise à jour vers ASP.NET MVC RC ce matin, et (selon le readme), j'ai placé ce qui suit dans le web.config de Views :

<pages validateRequest="false" 
       pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
       pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
       userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
    <controls>
        <add assembly="System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
    </controls>
</pages>

Donc, validateRequest devrait être false pour toutes les pages, non ? Qu'est-ce que j'ai raté ?

62voto

Levi Points 22222

En MVC, la validation a lieu au niveau du contrôleur, et non au niveau de la page. Pour comprendre pourquoi, considérez qu'au moment où l'action du contrôleur est exécutée, nous ne savons pas quelle vue sera choisie pour le rendu. (En fait, l'action du contrôleur peut même ne pas rendre de vue du tout ! Elle pourrait ouvrir une invite de téléchargement de fichier sur le client à la place). En outre, si un utilisateur soumet une entrée malveillante au serveur, il est trop tard pour faire quoi que ce soit lorsque la vue est rendue. Le contrôleur aura déjà enregistré l'entrée dangereuse dans la base de données.

Au lieu de cela, veuillez décorer le contrôleur ou l'action avec l'attribut [ValidateInput(false)]. Cela nous permettra de supprimer la validation de la demande pour ce contrôleur ou cette action.

17voto

Juan Carlos Velez Points 717

Il est nécessaire de décorer le contrôleur ou l'action avec l'attribut [ValidateInput(false)] et d'ajouter requestValidationMode="2.0" au fichier web.config : Exemple :

Le contrôleur :

    [ValidateInput(false)]
    public class MensajesController : Controller
    {
        //or in an action
        [ValidateInput(false)]
        [HttpPost]
        public ActionResult Create(FormCollection collection)
        {
        }
    }

Le fichier de configuration :

    <configuration>
        <system.web>
           <httpRuntime requestValidationMode="2.0"/>
        </system.web>
    </configuration>

2voto

Jarrod Dixon Points 9201

Nous avons un contrôleur de base dont nos contrôleurs héritent, ce qui nous permet de désactiver globalement la validation intrinsèque des requêtes ASP.NET :

    protected override void Initialize(RequestContext requestContext)
    {
        // no client input will be checked on any controllers
        ValidateRequest = false;
        base.Initialize(requestContext);
    }

Assurez-vous juste que vous valider toutes les entrées du client !

2voto

Brad Browne Points 21

J'ai eu un problème similaire en utilisant ASP.NET MVC 3 avec .NET 4.0 et le service de contrôle d'accès Windows Azure v2, où j'obtenais l'erreur :

System.Web.HttpRequestValidationException: A potentially dangerous Request.Form value was detected from the client (wresult="<t:RequestSecurityTo...").

et j'ai trouvé qu'une meilleure solution que de désactiver la validation était d'implémenter un RequestValidator personnalisé comme décrit dans cet article :

http://social.technet.microsoft.com/wiki/contents/articles/Windows-identity-foundation-wif-a-potentially-dangerous-request-form-value-was-detected-from-the-client-wresult-quot-lt-t-requestsecurityto-quot.aspx

public class SampleRequestValidator : RequestValidator
{
    protected override bool IsValidRequestString( HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex )
    {
        validationFailureIndex = 0;
        if ( requestValidationSource == RequestValidationSource.Form && collectionKey.Equals( WSFederationConstants.Parameters.Result, StringComparison.Ordinal ) )
        {
            SignInResponseMessage message = WSFederationMessage.CreateFromFormPost( context.Request ) as SignInResponseMessage;
            if ( message != null )
            {
                return true;
            }
        }
        return base.IsValidRequestString( context, value, requestValidationSource, collectionKey, out validationFailureIndex );
    }
}

La seule raison pour laquelle j'ai cherché à aller plus loin que la désactivation de la validation est que j'avais vu que cela fonctionnait sans désactiver la validation en suivant ce tutoriel dans le kit de formation de la plate-forme Windows Azure :

http://msdn.microsoft.com/en-us/WAZPlatformTrainingCourse_IntroToACSLabsV2

Quoi qu'il en soit, j'espère que ces informations seront utiles à quelqu'un et qu'elles fourniront une approche plus granulaire pour résoudre ce problème à l'avenir. Il convient de noter que le paramètre requestValidationMode="2.0" n'est pas nécessaire si vous mettez en œuvre le RequestValidator personnalisé.

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