2009-01-28 19 views
30

Tengo un formulario ASP.NET MVC que puede (generalmente lo hace) enviar una respuesta que desencadenaría el error "Se detectó un valor Request.Form potencialmente peligroso desde el cliente".¿Se puede anular la configuración ValidateRequest de una página?

Para tratar de evitar esto, he colocado ValidateRequest = "false" en la directiva de la página.

Único problema: ¡sigo recibiendo el error!

Ahora, todo estaba bien hasta que he actualizado a la ASP.NET MVC RC esta mañana, y (según el readme), colocado a la siguiente en el web.config Vistas:

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

Así, validateRequest debería ser falso para todas las páginas, ¿verdad? ¿Qué me estoy perdiendo?

+0

Las vistas web.config solo se aplican al navegar directamente a la carpeta Vistas, ¿verdad? – bzlm

+0

Sí, eso es correcto. –

Respuesta

62

En MVC, la validación tiene lugar en el nivel del controlador, no en el nivel de la página. Para ver por qué ocurre esto, considere que en el momento en que se está ejecutando la acción del controlador, no sabemos qué vista se elegirá para representar. (De hecho, ¡es posible que la acción del controlador ni siquiera represente una vista!) En su lugar, podría abrir una solicitud de descarga de archivo en el cliente). Además, si un usuario envía una entrada maliciosa al servidor, al demasiado tarde para hacer algo al respecto. El controlador ya habrá cometido la entrada peligrosa a la base de datos.

En su lugar, decore el controlador o la acción con el atributo [ValidateInput (false)]. Esto nos obligará a suprimir la validación de solicitud para ese controlador o acción.

+0

Esto ayudó mucho. –

+0

De hecho, ¡gracias! – Aaron

+0

+1 no solo para proporcionar una respuesta, sino también para explicar por qué funciona como tal. Siempre es bueno saber cómo hacer algo, pero siempre es mejor saber por qué hacer algo – JakeJ

2

Tenemos un controlador de base que nuestros controladores heredan de, lo que nos permite deshabilitar globalmente intrínseca de validación de solicitud ASP.NET:

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

Sólo asegúrese de que usted validar todas las entradas desde el cliente!

17

`s NECESARIO decorar el controlador o acción con el atributo [ValidateInput (false)] y añadir requestValidationMode = "2.0" al archivo web.config: Ejemplo:

El controlador:

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

El fichero de configuración:

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

Sí, es necesario establecer el modo de validación de la solicitud para .NET 4. Gracias por la actualización. –

2

I tenía un problema similar usando ASP.NET MVC 3 con .NET 4.0 y el v2 Windows Azure servicio de control de acceso, donde me gustaría obtener el error:

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

y ha encontrado una solución mejor que apagar la validación fue implementar un RequestValidator personalizado como se describe en este artículo:

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 única razón por la que miraba más allá de apagar la validación fue porque me había visto este trabajo sin tener que apagar la validación al seguir este tutorial en el kit de entrenamiento de la plataforma Windows Azure:

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

De todos modos, espero que esto sea de utilidad a alguien y podría proporcionar un enfoque más granular a la solución de este problema en el futuro. Cabe señalar que RequestValidationMode = "2.0" no es necesario si implementa el RequestValidator personalizado.

Cuestiones relacionadas