Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
lunes, 27 de septiembre de 2010
La validación de peticiones es un mecanismo integrado en ASP.NET que evita la entrada al sistema de valores considerados “peligrosos” para su integridad, como tags y otros elementos utilizables para la inyección de scripts (XSS) o introducción de valores no controlados.

Dado que está implementado a nivel de plataforma ASP.NET, los valores recibidos en parámetros de entrada son vigilados con ASP.NET MVC,  WebForms e incluso WebPages (la tecnología incluida en el nuevo WebMatrix).

Así, en cada petición son analizados los valores recibidos en el query string, cookies y campos de formulario, generándose una bonita pantalla de error cuando se identifica algo sospechoso:

Error de validación

Según el comportamiento por defecto, el framework realiza esta comprobación en el método IsDangerousString() de una clase interna de System.Web, llamada CrossSiteScriptingValidation. Si estudiamos su implementación, podemos observar que se comprueban los siguientes aspectos:
  • si se detecta algún ampersand “&”, se asegura que el siguiente carácter no sea una almohadilla “#”. Esto impide la entrada de entidades como "|"
  • si se detecta algún símbolo “<”, se asegura que el siguiente carácter no sea alfabético, el signo de exclamación “!”, interrogación “?” o la barra de división “/”. Esto evitará la entrada de etiquetas HTML (como <script>), el cierre de las mismas o la introducción de directivas o comentarios, aunque dejará pasar algunas expresiones que pueden ser construcciones lógicas como “a<1”.
Al violarse alguna de las reglas anteriores es cuando el sistema lanza la excepción HttpRequestValidationException, cuya representación en pantalla hemos visto anteriormente.

Aunque en la mayoría de ocasiones este mecanismo es muy útil, hay escenarios en los que se vuelve en nuestra contra. Por ejemplo, si en el formulario de datos hay campos destinados a la introducción de texto enriquecido, no nos permitirá la recepción de estos valores, pues normalmente incluirán tags HTML.

Veamos cómo podemos desactivar la comprobación de valores de entrada en distintos casos.

Desactivación en versiones anteriores a ASP.NET 4

Antes de la llegada de ASP.NET 4, en Webforms era posible desactivar la validación de peticiones simplemente añadiendo la directiva ValidateRequest=false en las páginas:

ValidateRequest en páginas
Para evitar la introducción de esta directiva en todas las páginas, podíamos hacerlo de forma global en el web.config, añadiendo el atributo validateRequest="false" en la sección <pages> del system.web:

ValidateRequest en web.config
También en ASP.NET MVC era posible desactivar este comportamiento muy fácilmente añadiendo a la acción del control destinataria de los datos del formulario el atributo [ValidateInput] enviándole false como argumento:

Atributo ValidateInput

Desactivación en ASP.NET 4

ASP.NET 4 ha introducido una serie de breaking changes que pueden hacer que aplicaciones web que antes funcionaban correctamente dejen de hacerlo. Uno de estos cambios es la forma en que se validan las peticiones.

Concretamente, se ha modificado el momento en el ciclo de vida del tratamiento de las peticiones donde se realiza la validación de la información de entrada. De esta forma, ahora se aplicarán también a servicios web, handlers o módulos HTTP personalizados, que antes no eran comprobados.

Así, por defecto, se realizará la validación antes de que entren en escena las directivas de página en Webforms o los atributos del controlador, por lo que se producirá la excepción de validación aunque la hayamos desactivado con ellos.

La forma de evitar esto es indicar en el web.config que queremos trabajar en modo compatible con versiones anteriores, introduciendo en el elemento <httpRuntime> el atributo requestValidationMode="2.0":

requestValidationMode

¿Y la desactivación para un único campo?

En apartados anteriores hemos visto cómo desactivar las comprobaciones de la petición sobre páginas (en el caso de Webforms) y acciones (en ASP.NET MVC). El problema de la aparición del error “se detectó un posible valor Request.Form peligroso” lo solucionaríamos muy rápidamente con las técnicas descritas.

Sin embargo, fijaos que al deshabilitar la validación lo hacemos sobre la petición completa; por ejemplo, si la desactivamos para una página donde existe un único campo en el que debe introducirse HTML estaríamos abriendo la posibilidad de que un usuario malintencionado introdujera código script en otros campos del formulario a los que posiblemente no prestemos tanta atención.

Curiosamente, analizando el código de ASP.NET he descubierto que existe un atajo que nos permite saltarnos la validación en un campo concreto del formulario, aunque la comprobación de peticiones se encuentre habilitada para la página, como es por defecto.

El hecho es que si el nombre del campo del formulario comienza por dos caracteres de subrayado, por ejemplo, “__Texto”, no se efectúan sobre él las comprobaciones de validación, probablemente para evitar que se realice sobre los campos especiales como “__VIEWSTATE ” o “__EVENTVALIDATION”.

Por tanto, si introducimos en un formulario cuadros de texto o textareas en los que queremos saltarnos esta validación, basta con nombrarlos siguiendo esta regla, como en el siguiente ejemplo, para ASP.NET MVC:

Uso en ASP.NET MVC
Asimismo, puede utilizarse con ASP.NET Webforms. En este caso, sólo debemos asegurarnos de que el nombre (el atributo name) asignado en cliente al control comience por el doble subrayado:

Uso en WebformsPublicado en: Variable not found.

9 Comentarios:

MoRpEr dijo...

gracias justamente estoy trabajando en una vista que permita en uno de los campos introducir HTML ,pero como seria la desactivacion del control para dicho campo ya que este lo genero con los HTML HELPERS desde el modelo de entidad?

josé M. Aguilar dijo...

Hola, Morper.

Si estás desarrollando en MVC 3, puedes utilizar directamente el atributo [AllowHtml] sobre la propiedad del modelo en la que te interese que se introduzca HTML.

Puedes leer más sobre ello aquí: http://davidhayden.com/blog/dave/archive/2011/01/16/AllowHtmlAttributeASPNETMVC3.aspx.

Saludos!

Anónimo dijo...

Muchas gracias!!!

esperemos que M$ nunca se den cuenta de esto...

Anónimo dijo...

Genial la solución.
Excelente aporte Gracias

Anónimo dijo...

Excelente, Muchas Gracias, perfecta la forma de explicar, me sirvio mucho.

Saludos.

Anónimo dijo...

buenos dias amigo ya lo hice y me funciono de maravilla pero me guarda la informacion mal, formareguero cuando hay la tilde o ñ

B-Learning Juan Carlos Camacho dijo...

Excelente aporte!!,justo era lo que necesitaba me ayudo mucho

MASTER dijo...

Gracias por tu ayuda.

Unknown dijo...

Gracias por la explicacion, falta mucho por asegurar saludos