Se detectó un valor Request.Form potencialmente peligroso del cliente

Cada vez que un usuario publica algo que contiene < o > en una página de mi aplicación web, recibo esta excepción.

No quiero entrar en la discusión sobre la inteligencia de lanzar una excepción o bloquear una aplicación web completa porque alguien ingresó un personaje en un cuadro de texto, pero estoy buscando una forma elegante de manejar esto.

Atrapando la excepción y mostrando

Se ha producido un error. Regrese y vuelva a escribir todo el formulario nuevamente, pero esta vez no use <

no parece lo suficientemente profesional para mí.

La desactivación de la validación posterior ( validateRequest="false" ) definitivamente evitará este error, pero dejará la página vulnerable a una serie de ataques.

Idealmente: cuando se produce una publicación posterior que contiene caracteres restringidos HTML, ese valor publicado en la colección Formulario se codificará automáticamente en HTML. Entonces, la propiedad .Text de mi cuadro de texto será something & lt; html & gt; something & lt; html & gt;

¿Hay alguna manera de que pueda hacer esto desde un controlador?

Creo que lo estás atacando desde el ángulo equivocado al intentar codificar todos los datos publicados.

Tenga en cuenta que un ” < " también podría provenir de otras fonts externas, como un campo de base de datos, una configuración, un archivo, un feed, etc.

Además, " < " no es inherentemente peligroso. Solo es peligroso en un contexto específico: cuando se escriben cadenas que no han sido codificadas para salida HTML (debido a XSS).

En otros contextos, diferentes subcadenas son peligrosas; por ejemplo, si escribe una URL proporcionada por el usuario en un enlace, la subcadena " javascript: " puede ser peligrosa. El carácter de comilla simple por otro lado es peligroso al interpolar cadenas en consultas SQL, pero es perfectamente seguro si es parte de un nombre enviado desde un formulario o leído desde un campo de base de datos.

La conclusión es: no se puede filtrar la entrada aleatoria de caracteres peligrosos, porque cualquier personaje puede ser peligroso en las circunstancias adecuadas. Debería codificar en el punto donde algunos caracteres específicos pueden volverse peligrosos porque cruzan a un sublengua diferente donde tienen un significado especial. Cuando escribe una cadena en HTML, debe codificar los caracteres que tienen un significado especial en HTML, utilizando Server.HtmlEncode. Si pasa una cadena a una statement SQL dinámica, debe codificar caracteres diferentes (o mejor, deje que el marco lo haga por usted usando declaraciones preparadas o similares).

Cuando esté seguro de que codifica HTML en cualquier lugar donde pase cadenas a HTML, establezca validateRequest="false" en la directiva < %@ Page ... %> en su archivo .aspx .

En .NET 4 es posible que deba hacer un poco más. A veces también es necesario agregar a web.config ( referencia ).

Hay una solución diferente a este error si está utilizando ASP.NET MVC:

  • ASP.NET MVC – ¿Las páginas validateRequest = falso no funcionan?
  • ¿Por qué ValidateInput (False) no funciona?
  • ASP.NET MVC RC1, VALIDATEINPUT, UNA POTENCIAL PETICIÓN PELIGROSA Y EL PITFALL

Muestra C #:

 [HttpPost, ValidateInput(false)] public ActionResult Edit(FormCollection collection) { // ... } 

Muestra de Visual Basic:

  _ Function Edit(ByVal collection As FormCollection) As ActionResult ... End Function 

En ASP.NET MVC (comenzando en la versión 3), puede agregar el atributo AllowHtml a una propiedad en su modelo.

Permite que una solicitud incluya marcado HTML durante el enlace del modelo omitiendo la validación de solicitud para la propiedad.

 [AllowHtml] public string Description { get; set; } 

Si está en .NET 4.0, asegúrese de agregar esto en su archivo web.config dentro de las tags :

  

En .NET 2.0, la validación de solicitudes solo se aplica a solicitudes aspx . En .NET 4.0 esto se amplió para incluir todas las solicitudes. Puede volver solo a realizar la validación de XSS al procesar .aspx especificando:

 requestValidationMode="2.0" 

Puede deshabilitar la solicitud de validar por completo especificando:

 validateRequest="false" 

Para ASP.NET 4.0, puede permitir el marcado como entrada para páginas específicas en lugar de todo el sitio al ponerlo todo en un elemento . Esto asegurará que todas las otras páginas estén seguras. NO necesita colocar ValidateRequest="false" en su página .aspx.

  ...       ...  

Es más seguro controlar esto dentro de su web.config, porque puede ver a nivel del sitio qué páginas permiten el marcado como entrada.

Aún necesita validar la entrada de forma programática en las páginas donde la validación de solicitud está deshabilitada.

Las respuestas anteriores son geniales, pero nadie dijo cómo excluir un solo campo de la validación de las inyecciones de HTML / JavaScript. No sé sobre versiones anteriores, pero en MVC3 Beta puedes hacer esto:

 [HttpPost, ValidateInput(true, Exclude = "YourFieldName")] public virtual ActionResult Edit(int id, FormCollection collection) { ... } 

Esto aún valida todos los campos excepto el excluido. Lo bueno de esto es que sus atributos de validación todavía validan el campo, pero simplemente no obtiene las excepciones “Se detectó un valor de Request.Form potencialmente peligroso desde el cliente”.

Lo he usado para validar una expresión regular. Creé mi ValidationAttribute para ver si la expresión regular es válida o no. Como las expresiones regulares pueden contener algo que se parece a un script, apliqué el código anterior: la expresión regular aún se verifica si es válida o no, pero no si contiene scripts o HTML.

En ASP.NET MVC necesita establecer requestValidationMode = “2.0” y validateRequest = “false” en web.config, y aplicar un atributo ValidateInput a su acción de controlador:

       

y

 [Post, ValidateInput(false)] public ActionResult Edit(string message) { ... } 

Puede codificar HTML en el contenido del cuadro de texto, pero desafortunadamente eso no evitará que ocurra la excepción. Según mi experiencia, no hay forma de evitarlo, y debes desactivar la validación de la página. Al hacer eso, estás diciendo: “Tendré cuidado, lo prometo”.

Para MVC, ignore la validación de entrada agregando

[ValidateInput (falso)]

encima de cada acción en el controlador.

Puede detectar ese error en Global.asax. Todavía quiero validar, pero mostrar un mensaje apropiado. En el blog que figura a continuación, una muestra como esta estaba 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(); } } 

Redirigir a otra página también parece una respuesta razonable a la excepción.

http://www.romsteady.net/blog/2007/06/how-to-catch-httprequestvalidationexcep.html

Tenga en cuenta que algunos controles .NET codificarán HTML automáticamente la salida. Por ejemplo, establecer la propiedad .Text en un control TextBox lo codificará automáticamente. Eso específicamente significa convertir < en < , > en > y & en & . Así que ten cuidado de hacer esto ...

 myTextBox.Text = Server.HtmlEncode(myStringFromDatabase); // Pseudo code 

Sin embargo, la propiedad .Text para HyperLink, Literal y Label no codificará las cosas en HTML, por lo que envuelve Server.HtmlEncode (); todo lo que se establece en estas propiedades es obligatorio si desea evitar para que se envíe a su página y se ejecute posteriormente.

Haga un poco de experimentación para ver qué se codifica y qué no.

La respuesta a esta pregunta es simple:

 var varname = Request.Unvalidated["parameter_name"]; 

Esto inhabilitaría la validación para la solicitud particular.

En el archivo web.config, dentro de las tags, inserte el elemento httpRuntime con el atributo requestValidationMode = “2.0”. También agregue el atributo validateRequest = “false” en el elemento pages.

Ejemplo:

        

Si no desea deshabilitar ValidateRequest, debe implementar una función de JavaScript para evitar la excepción. No es la mejor opción, pero funciona.

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

Luego, en el código subyacente, en el evento PageLoad, agregue el atributo a su control con el siguiente código:

 Me.TextBox1.Attributes.Add("OnKeyPress", "return AlphanumericValidation(event);") 

Parece que nadie ha mencionado el siguiente sin embargo, pero me solucionó el problema. Y antes de que alguien diga que sí, es Visual Basic … puaj.

 < %@ Page Language="vb" AutoEventWireup="false" CodeBehind="Example.aspx.vb" Inherits="Example.Example" **ValidateRequest="false"** %> 

No sé si hay inconvenientes, pero para mí esto funcionó increíble.

Otra solución es:

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

En ASP.NET, puede detectar la excepción y hacer algo al respecto, como mostrar un mensaje amistoso o redirigir a otra página … También existe la posibilidad de que pueda manejar la validación usted mismo …

Mostrar mensaje amigable:

 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(); } } 

Supongo que podrías hacerlo en un módulo; pero eso deja abiertas algunas preguntas; ¿y si quieres guardar la entrada en una base de datos? De repente, debido a que estás guardando datos codificados en la base de datos, terminas confiando en la información de entrada que probablemente sea una mala idea. Lo ideal sería almacenar datos sin codificar en la base de datos y la encoding cada vez.

Desactivar la protección en un nivel por página y luego codificar cada vez es una mejor opción.

En lugar de utilizar Server.HtmlEncode, debe consultar la biblioteca Anti-XSS más nueva y completa del equipo de Microsoft ACE.

Si está utilizando Framework 4.0, entonces la entrada en el web.config ()

      

Si está utilizando Framework 4.5 entonces la entrada en el web.config (requestValidationMode = “2.0”)

     

Si solo quieres una página, en tu archivo aspx debes poner la primera línea como esta:

 < %@ Page EnableEventValidation="false" %> 

si ya tiene algo como < % @ Page, solo agregue el resto => EnableEventValidation="false" %>

Recomiendo no hacerlo.

Las otras soluciones aquí son agradables, sin embargo, es un poco de dolor real en la parte trasera tener que aplicar [AllowHtml] a cada propiedad del modelo, especialmente si tiene más de 100 modelos en un sitio de un tamaño decente.

Si, como yo, quieres desactivar esta función (en mi humilde opinión) del sitio, puedes anular el método Execute () en tu controlador base (si aún no tienes un controlador base, te sugiero que hagas uno, pueden serlo). bastante útil para aplicar la funcionalidad común).

  protected override void Execute(RequestContext requestContext) { // Disable requestion validation (security) across the whole site ValidateRequest = false; base.Execute(requestContext); } 

Solo asegúrate de que estás codificando HTML todo lo que se bombea a las vistas que provienen de la entrada del usuario (es un comportamiento predeterminado en ASP.NET MVC 3 con Razor de todos modos, así que a menos que por alguna extraña razón estés usando Html.Raw () no debería requerir esta característica.

Estaba recibiendo este error también.

En mi caso, un usuario ingresó un carácter a a en un Nombre de rol (con respecto al proveedor de membresía de ASP.NET).

Paso el nombre de la función a un método para otorgar usuarios a esa función y la solicitud de entrada $.ajax fallaba miserablemente …

Hice esto para resolver el problema:

En lugar de

 data: { roleName: '@Model.RoleName', users: users } 

Hacer esto

 data: { roleName: '@Html.Raw(@Model.RoleName)', users: users } 

@Html.Raw hizo el truco.

roleName="Cadastro bás" el nombre de la función como valor HTML roleName="Cadastro bás" . Este valor con la entidad HTML á estaba siendo bloqueado por ASP.NET MVC. Ahora obtengo el valor del parámetro roleName la manera que debería ser: roleName="Cadastro Básico" y el motor ASP.NET MVC ya no bloqueará la solicitud.

Porque

ASP.NET valida por defecto todos los controles de entrada para los contenidos potencialmente inseguros que pueden conducir a scripts de sitios cruzados (XSS) y inyecciones de SQL . Por lo tanto, no permite dicho contenido lanzando la excepción anterior. De forma predeterminada, se recomienda permitir que esta verificación se realice en cada devolución de datos.

Solución

En muchas ocasiones, debe enviar contenido HTML a su página a través de Rich TextBoxes o Rich Text Editors. En ese caso, puede evitar esta excepción estableciendo la etiqueta ValidateRequest en la directiva @Page en falso.

 < %@ Page Language="C#" AutoEventWireup="true" ValidateRequest = "false" %> 

Esto deshabilitará la validación de las solicitudes para la página que ha establecido el indicador ValidateRequest en falso. Si desea desactivar esto, verifique a través de su aplicación web; deberás configurarlo en falso en tu sección web.config

  

Para los frameworks .NET 4.0 o posteriores, también necesitará agregar la siguiente línea en la sección para hacer que lo anterior funcione.

  

Eso es. Espero que esto te ayude a deshacerte del problema anterior.

Referencia por: Error ASP.Net: Se detectó un valor Request.Form potencialmente peligroso del cliente

Desactive la validación de la página si realmente necesita los caracteres especiales, como, > , < , etc. Luego, asegúrese de que cuando se muestre la entrada del usuario, los datos estén codificados en HTML.

Existe una vulnerabilidad de seguridad con la validación de la página, por lo que puede omitirse. Además, la validación de página no debe confiarse únicamente.

Ver: http://www.procheckup.com/PDFs/bypassing-dot-NET-ValidateRequest.pdf

Encontré una solución que usa JavaScript para codificar los datos, que se decodifica en .NET (y no requiere jQuery).

  • Convierta el cuadro de texto en un elemento HTML (como textarea) en lugar de un ASP.
  • Agrega un campo oculto.
  • Agregue la siguiente función de JavaScript a su encabezado.

    función boo () {targetText = document.getElementById (“HiddenField1”); sourceText = document.getElementById (“userbox”); targetText.value = escape (sourceText.innerText); }

En su área de texto, incluya un onchange que llame a boo ():

  

Finalmente, en .NET, use

 string val = Server.UrlDecode(HiddenField1.Value); 

Soy consciente de que esto es unidireccional: si necesita dos vías, deberá ser creativo, pero esto proporciona una solución si no puede editar el archivo web.config

Aquí hay un ejemplo que I (MC9000) ideó y usó a través de 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 }); }); 

Y el marcado:

    

Esto funciona genial Si un pirata informático intenta publicar evitando JavaScript, ellos solo verán el error. También puede guardar todos estos datos codificados en una base de datos, luego descomprimirlos (en el lado del servidor) y analizar y verificar si hay ataques antes de mostrarlos en otro lugar.

También puede usar la función de escape (cadena) de JavaScript para reemplazar los caracteres especiales. Luego, el servidor usa el Servidor. URLDecode (cadena) para volver a cambiarlo.

De esta forma, no tiene que desactivar la validación de entrada y será más claro para otros progtwigdores que la cadena puede tener contenido HTML.

Terminé usando JavaScript antes de cada devolución para verificar los caracteres que no deseaba, como por ejemplo:

  function checkFields() { var tbs = new Array(); tbs = document.getElementsByTagName("input"); var isValid = true; for (i=0; i') != -1) { alert('<> symbols not allowed.'); isValid = false; } } } return isValid; } 

De acuerdo, mi página es principalmente de entrada de datos, y hay muy pocos elementos que hagan devoluciones de datos, pero al menos se conservan sus datos.

Siempre que estos sean solo caracteres “< " y ">” (y no la comilla doble) y los esté usando en contexto como

Si solo quieres decirles a tus usuarios que no se van a usar, PERO no quieres que se procese / publique todo el formulario (y pierdas toda la información) de antemano, ¿no podrías poner simplemente un Validador en el campo para detectar esos (y tal vez otros personajes potencialmente peligrosos)

Ninguna de las sugerencias funcionó para mí. No quería desactivar esta función para todo el sitio web porque el 99% de las veces no quiero que mis usuarios coloquen HTML en los formularios web. Acabo de crear mi propio método de trabajo porque soy el único que usa esta aplicación en particular. I convert the input to HTML in the code behind and insert it into my database.

You can use something like:

 var nvc = Request.Unvalidated().Form; 

Later, nvc["yourKey"] should work.