it-swarm-es.tech

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, se produce esta excepción.

No quiero entrar en la discusión sobre lo inteligente que es 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, vuelva atrás y vuelva a escribir todo el formulario, pero esta vez no utilice <

no me parece lo suficientemente profesional.

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 ocurra una devolución que contenga caracteres restringidos de HTML, ese valor publicado en la colección de Formularios se codificará automáticamente en HTML. Por lo tanto, la propiedad .Text de mi cuadro de texto será something & lt; html & gt;

¿Hay alguna manera de hacer esto desde un controlador?

1379
Radu094

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 fuentes 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: al escribir cadenas que no se han codificado en la salida HTML (debido a XSS).

En otros contextos, diferentes sub-cadenas son peligrosas, por ejemplo, si escribe una URL proporcionada por el usuario en un enlace, la sub-cadena "javascript:" puede ser peligrosa. Por otra parte, el carácter de comillas simples 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 puede filtrar la entrada aleatoria de caracteres peligrosos, ya que cualquier carácter puede ser peligroso en las circunstancias adecuadas. Debe codificar en el punto en el que algunos caracteres específicos puedan volverse peligrosos porque se cruzan en un sub-lenguaje 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 declaración de SQL dinámico, debe codificar diferentes caracteres (o mejor, deje que el marco lo haga por usted utilizando instrucciones preparadas o similares).

Cuando está seguro de que codifica en HTML en todas partes que pasa cadenas a HTML, luego establezca validateRequest="false" en la directiva <%@ Page ... %> en su (s) archivo (s) .aspx.

En .NET 4 puede que tengas que hacer un poco más. A veces también es necesario agregar <httpRuntime requestValidationMode="2.0" /> a web.config ( reference ).

1028
JacquesB

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

Muestra de C #:

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

Ejemplo de Visual Basic:

<AcceptVerbs(HttpVerbs.Post), ValidateInput(False)> _
Function Edit(ByVal collection As FormCollection) As ActionResult
    ...
End Function
482
Zack Peterson

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

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

[AllowHtml]
public string Description { get; set; }
384
Anthony Johnston

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

<httpRuntime requestValidationMode="2.0" />

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

requestValidationMode="2.0"

Puede deshabilitar la solicitud de validación enteramente especificando:

validateRequest="false"
206
JordanC

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

<configuration>
...
  <location path="MyFolder/.aspx">
    <system.web>
      <pages validateRequest="false" />
      <httpRuntime requestValidationMode="2.0" />
    </system.web>
  </location>
...
</configuration>

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

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

108
Carter Medlin

Las respuestas anteriores son excelentes, pero nadie dijo cómo excluir un solo campo para que no sea validado para inyecciones de HTML/JavaScript. No sé acerca de versiones anteriores, pero en MVC3 Beta puedes hacer esto:

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

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

He usado esto para validar una expresión regular. He creado mi propio 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 todavía se está verificando si es válida o no, pero no si contiene scripts o HTML.

70
gligoran

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

<httpRuntime requestValidationMode="2.0"/>

<configuration>
    <system.web>
        <pages validateRequest="false" />
    </system.web>
</configuration>

y

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

Puede codificar HTML cuadro de texto, pero desafortunadamente eso no detendrá la excepción. En mi experiencia, no hay manera de evitarlo, y tienes que deshabilitar la validación de la página. Al hacer eso estás diciendo: "Tendré cuidado, lo prometo".

45
Pavel Chuchuva

Para MVC, ignore la validación de entrada agregando 

[ValidateInput (falso)]

por encima de cada acción en el controlador.

42
A.Dara

Puedes atrapar ese error en Global.asax. Todavía quiero validar, pero mostrar un mensaje apropiado. En el blog que aparece 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 ser una respuesta razonable a la excepción.

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

41
BenMaddox

Tenga en cuenta que algunos controles .NET codificarán automáticamente la salida en HTML. Por ejemplo, establecer la propiedad .Text en un control TextBox lo codificará automáticamente. Eso significa específicamente convertir < en &lt;, > en &gt; y & en &amp;. 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á HTML, por lo que envuelve Server.HtmlEncode (); alrededor de cualquier cosa que se establezca en estas propiedades es imprescindible si desea evitar que <script> window.location = "http://www.google.com"; </script> se imprima en su página y se ejecute posteriormente.

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

33
Dominic Pettifer

La respuesta a esta pregunta es simple:

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

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

31
flakomalo

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

Ejemplo:

<configuration>
  <system.web>
   <httpRuntime requestValidationMode="2.0" />
  </system.web>
  <pages validateRequest="false">
  </pages>
</configuration>
27
Mahdi jokar

Si no desea desactivar ValidateRequest, necesita 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 detrás, en el evento PageLoad, agregue el atributo a su control con el siguiente código:

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

Parece que nadie ha mencionado lo siguiente todavía, pero soluciona el problema para mí. Y antes de que alguien diga sí, es Visual Basic ... asco.

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

No sé si hay alguna desventaja, pero para mí esto funcionó de maravilla.

20
Piercy

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

Si está utilizando framework 4.0, la entrada en web.config (<pages validateRequest = "false" />)

<configuration>
    <system.web>
        <pages validateRequest="false" />
    </system.web>
</configuration>

Si está utilizando framework 4.5, la entrada en web.config (requestValidationMode = "2.0")

<system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" requestValidationMode="2.0"/>
</system.web>

Si solo desea una sola página, en su archivo aspx debe poner la primera línea así:

<%@ Page EnableEventValidation="false" %>

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

Recomiendo no hacerlo.

14
Durgesh Pandey

En ASP.NET, puede detectar la excepción y hacer algo al respecto, como mostrar un mensaje amigable o redirigir a otra página ... También existe la posibilidad de que pueda manejar la validación por sí 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();
    }
}
13
Jaider

Supongo que podrías hacerlo en un módulo; pero eso deja abiertas algunas preguntas; ¿Qué sucede si desea guardar la entrada en una base de datos? De repente, debido a que está guardando datos codificados en la base de datos, terminará confiando en los datos de entrada, lo que probablemente sea una mala idea. Lo ideal es almacenar los datos sin codificar sin procesar en la base de datos y la codificación cada vez.

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

En lugar de usar Server.HtmlEncode, debería mirar el biblioteca Anti-XSS más reciente y más completo del equipo de Microsoft ACE.

12
blowdart

Las otras soluciones aquí son Niza, sin embargo, es un 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 tamaño decente.

Si, como yo, quiere desactivar esta característica (IMHO bastante inútil) fuera del sitio, puede anular el método Execute () en su controlador base (si aún no tiene un controlador base, le sugiero que haga uno, pueden ser bastante útil para aplicar 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 en HTML todo lo que se bombea a las vistas que provienen de la entrada del usuario (de todos modos, es el comportamiento predeterminado en ASP.NET MVC 3 con Razor, así que a menos que por alguna extraña razón estés usando Html.Raw ()) No debería requerir esta característica.

10
magritte

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 se puede omitir. Además, la validación de la página no se debe confiar únicamente en.

Consulte: http://web.archive.org/web/20080913071637/http://www.procheckup.com:80/PDFs/bypassing-dot-NET-ValidateRequest.pdf

9
woany

Causa

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

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

<%@ 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 deshabilitar esto, verifique en toda su aplicación web; deberás configurarlo en falso en tu web.config <system.web> sección

<pages validateRequest ="false" />

Para marcos .NET 4.0 o superiores, también deberá agregar la siguiente línea en la sección <system.web> para que funcione lo anterior.

<httpRuntime requestValidationMode = "2.0" />

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

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

9
vakeel

Encontré una solución que utiliza 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 ASP uno.
  • Añade un campo oculto.
  • Agregue la siguiente función de JavaScript a su encabezado.

    function 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 ():

<textarea id="userbox"  onchange="boo();"></textarea>

Finalmente, en .NET, use

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

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

Aquí hay un ejemplo que se me ocurrió (MC9000) y uso 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:

<asp:HiddenField ID="hidHTML" runat="server" />
<textarea id="txtHTML"></textarea>
<asp:Button ID="btnMyPostbackButton" runat="server" Text="Post Form" />

Esto funciona muy bien. Si un hacker intenta publicar a través de JavaScript sin pasar, solo verán el error. También puede guardar todos estos datos codificados en una base de datos, luego, eliminarlos (en el lado del servidor) y analizar y verificar si hay ataques antes de mostrarlos en otro lugar.

9
Jason Shuler

Yo también estaba recibiendo este error.

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

Pasé el nombre del rol a un método para otorgar a los usuarios ese rol y la solicitud de publicación $.ajax estaba fallando 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.

Estaba obteniendo el nombre del rol como valor HTML roleName="Cadastro b&#225;s". ASP.NET MVC estaba bloqueando este valor con la entidad HTML &#225;. Ahora obtengo el valor del parámetro roleName como debería ser: roleName="Cadastro Básico" y el motor ASP.NET MVC ya no bloqueará la solicitud.

9
Leniel Maccaferri

También puede usar la función escape (string) de JavaScript para reemplazar los caracteres especiales. Luego use el lado del servidor Server. URLDecode (cadena) para volver a cambiarlo.

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

7
Trisped

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

<asp:Button runat="server" ID="saveButton" Text="Save" CssClass="saveButton" OnClientClick="return checkFields()" />

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

Concedido, mi página es en su mayoría entrada de datos, y hay muy pocos elementos que hacen devoluciones de datos, pero al menos se conservan sus datos.

6
Ryan

Siempre y cuando estos sean los caracteres solo "<" y ">" (y no la comilla doble en sí mismos) y los esté usando en el contexto como <input value = " this " /> , estás a salvo (mientras que para <textarea> este </textarea> serías vulnerable, por supuesto). Eso puede simplificar su situación, pero para cualquier cosa más use una de las otras soluciones publicadas.

4
Paweł Hajdan

Si solo quiere decirles a sus usuarios que <y> no deben usarse, PERO, no quiere que todo el formulario sea procesado/publicado de nuevo (y pierde toda la información) de antemano. validador alrededor del campo para seleccionar esos (y quizás otros caracteres potencialmente peligrosos)?

4
Captain Toad

Puedes usar algo como:

var nvc = Request.Unvalidated().Form;

Más tarde, nvc["yourKey"] debería funcionar.

4
Ady Levy

Ninguna de las sugerencias funcionó para mí. No quería desactivar esta función para todo el sitio web de todos modos porque el 99% del tiempo no quiero que mis usuarios coloquen HTML en formularios web. Acabo de crear mi propio método de trabajo ya que soy el único que usa esta aplicación en particular. Convierto la entrada a HTML en el código que está detrás y la inserto en mi base de datos.

4
Mike S.

Puede automáticamente codificar el campo HTML en el Cuaderno de modelos personalizado. Mi solución es diferente, puse el error en ModelState y muestro un mensaje de error cerca del campo. Es fácil modificar este código para codificar automáticamente 

 public class AppModelBinder : DefaultModelBinder
    {
        protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
        {
            try
            {
                return base.CreateModel(controllerContext, bindingContext, modelType);
            }
            catch (HttpRequestValidationException e)
            {
                HandleHttpRequestValidationException(bindingContext, e);
                return null; // Encode here
            }
        }
        protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext,
            PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
        {
            try
            {
                return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
            }
            catch (HttpRequestValidationException e)
            {
                HandleHttpRequestValidationException(bindingContext, e);
                return null; // Encode here
            }
        }

        protected void HandleHttpRequestValidationException(ModelBindingContext bindingContext, HttpRequestValidationException ex)
        {
            var valueProviderCollection = bindingContext.ValueProvider as ValueProviderCollection;
            if (valueProviderCollection != null)
            {
                ValueProviderResult valueProviderResult = valueProviderCollection.GetValue(bindingContext.ModelName, skipValidation: true);
                bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
            }

            string errorMessage = string.Format(CultureInfo.CurrentCulture, "{0} contains invalid symbols: <, &",
                     bindingContext.ModelMetadata.DisplayName);

            bindingContext.ModelState.AddModelError(bindingContext.ModelName, errorMessage);
        }
    }

En Application_Start:

ModelBinders.Binders.DefaultBinder = new AppModelBinder();

Tenga en cuenta que funciona solo para campos de formulario. El valor peligroso no se pasa al modelo del controlador, pero se almacena en ModelState y se puede volver a mostrar en el formulario con un mensaje de error. 

Los caracteres peligrosos en la URL se pueden manejar de esta manera:

private void Application_Error(object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    HttpContext httpContext = HttpContext.Current;

    HttpException httpException = exception as HttpException;
    if (httpException != null)
    {
        RouteData routeData = new RouteData();
        routeData.Values.Add("controller", "Error");
        var httpCode = httpException.GetHttpCode();
        switch (httpCode)
        {
            case (int)HttpStatusCode.BadRequest /* 400 */:
                if (httpException.Message.Contains("Request.Path"))
                {
                    httpContext.Response.Clear();
                    RequestContext requestContext = new RequestContext(new HttpContextWrapper(Context), routeData);
                    requestContext.RouteData.Values["action"] ="InvalidUrl";
                    requestContext.RouteData.Values["controller"] ="Error";
                    IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
                    IController controller = factory.CreateController(requestContext, "Error");
                    controller.Execute(requestContext);
                    httpContext.Server.ClearError();
                    Response.StatusCode = (int)HttpStatusCode.BadRequest /* 400 */;
                }
                break;
        }
    }
}

ErrorController: 

public class ErrorController : Controller
 {
   public ActionResult InvalidUrl()
   {
      return View();
   }
}   
3
Sel

Debe usar el método Server.HtmlEncode para proteger su sitio de entradas peligrosas.

Más información aquí

3
bastos.sergio

Como se indica en mi comentario a la respuesta de Sel , esta es nuestra extensión a un validador de solicitudes personalizado.

public class SkippableRequestValidator : RequestValidator
{
    protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
    {
        if (collectionKey != null && collectionKey.EndsWith("_NoValidation"))
        {
            validationFailureIndex = 0;
            return true;
        }

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

Para aquellos que no están usando el enlace de modelo, quienes están extrayendo cada parámetro del Formulario de Solicitud, quienes están seguros de que el texto de entrada no causará daño, hay otra manera. No es una gran solución pero hará el trabajo. 

Desde el lado del cliente, codifíquelo como uri y luego envíelo.
p.ej: 

encodeURIComponent($("#MsgBody").val());  

Desde el lado del servidor, acéptalo y decodifícalo como uri.
p.ej: 

string temp = !string.IsNullOrEmpty(HttpContext.Current.Request.Form["MsgBody"]) ?
System.Web.HttpUtility.UrlDecode(HttpContext.Current.Request.Form["MsgBody"]) : 
null;  

string temp = !string.IsNullOrEmpty(HttpContext.Current.Request.Form["MsgBody"]) ?
System.Uri.UnescapeDataString(HttpContext.Current.Request.Form["MsgBody"]) : 
null; 

por favor, busque las diferencias entre UrlDecode y UnescapeDataString

2
Wahid Masud

Por último, pero no menos importante, tenga en cuenta que los controles de enlace de datos de ASP.NET automáticamente codifican valores durante el enlace de datos. Esto cambia el comportamiento predeterminado de todos los controles ASP.NET (TextBox, Label, etc.) contenidos en la ItemTemplate. El siguiente ejemplo muestra (ValidateRequest se establece en falso):

aspx

<%@ Page Language="C#" ValidateRequest="false" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication17._Default" %> <html> <body>
    <form runat="server">
        <asp:FormView ID="FormView1" runat="server" ItemType="WebApplication17.S" SelectMethod="FormView1_GetItem">
            <ItemTemplate>
                <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
                <asp:Label ID="Label1" runat="server" Text="<%#: Item.Text %>"></asp:Label>
                <asp:TextBox ID="TextBox2" runat="server" Text="<%#: Item.Text %>"></asp:TextBox>
            </ItemTemplate>
        </asp:FormView>
    </form> 

código detrás

public partial class _Default : Page
{
    S s = new S();

    protected void Button1_Click(object sender, EventArgs e)
    {
        s.Text = ((TextBox)FormView1.FindControl("TextBox1")).Text;
        FormView1.DataBind();
    }

    public S FormView1_GetItem(int? id)
    {
        return s;
    }
}

public class S
{
    public string Text { get; set; }
}
  1. Valor de envío del caso: &#39;

Label1.Text value: &#39;

TextBox2.Text value: &amp;#39;

  1. Valor de envío del caso: <script>alert('attack!');</script>

Label1.Text value: <script>alert('attack!');</script>

TextBox2.Text value: &lt;script&gt;alert(&#39;attack!&#39;);&lt;/script&gt;

1
dpant

Para aquellos de nosotros que seguimos atascados en formularios web, encontré la siguiente solución que le permite deshabilitar solo la validación en un campo. (Odiaría deshabilitarlo para toda la página).

VB.NET:

Public Class UnvalidatedTextBox
    Inherits TextBox
    Protected Overrides Function LoadPostData(postDataKey As String, postCollection As NameValueCollection) As Boolean
        Return MyBase.LoadPostData(postDataKey, System.Web.HttpContext.Current.Request.Unvalidated.Form)
    End Function
End Class

DO#:

public class UnvalidatedTextBox : TextBox
{
    protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
    {
        return base.LoadPostData(postDataKey, System.Web.HttpContext.Current.Request.Unvalidated.Form);
    }
}

Ahora solo use <prefix:UnvalidatedTextBox id="test" runat="server" /> en lugar de <asp:TextBox, y debería permitir todos los caracteres (¡esto es perfecto para los campos de contraseña!)

1
Peter

Sé que esta pregunta es sobre la publicación de formularios, pero me gustaría agregar algunos detalles para las personas que recibieron este error en otras circunstancias. También podría ocurrir en un controlador utilizado para implementar un servicio web. 

Supongamos que su cliente web envía POST o solicitudes PUT utilizando ajax y envía texto json o xml o datos sin procesar (contenido de un archivo) a su servicio web. Debido a que su servicio web no necesita obtener información de un encabezado de tipo de contenido, su código de JavaScript no estableció este encabezado en su solicitud de ajax. Pero si no configura este encabezado en una solicitud ajax POST/PUT, Safari puede agregar este encabezado: "Content-Type: application/x-www-form-urlencoded". Observé que en Safari 6 en iPhone, pero otras versiones de Safari/OS o Chrome pueden hacer lo mismo. Entonces, al recibir este encabezado de tipo de contenido, alguna parte de .NET Framework asume que la estructura de datos del cuerpo de la solicitud corresponde a una publicación en un formulario html mientras que no lo hace y se levantó una excepción HttpRequestValidationException. Lo primero que debe hacer es, obviamente, establecer siempre el encabezado Content-Type en cualquier cosa que no sea un tipo MIME en una solicitud ajax POST/PUT, incluso si es inútil para su servicio web.

También descubrí este detalle:
En estas circunstancias, la excepción HttpRequestValidationException se incrementa cuando el código intenta acceder a la colección HttpRequest.Params. Pero sorprendentemente, esta excepción no se levanta cuando accede a la colección HttpRequest.ServerVariables. Esto muestra que si bien estas dos colecciones parecen ser casi idénticas, una accede a los datos de solicitud a través de controles de seguridad y la otra no.

1
figolu

En .Net 4.0 y en adelante, que es el caso habitual, ponga la siguiente configuración en system.web

<system.web>
     <httpRuntime requestValidationMode="2.0" />
1
Kiran Chaudhari

en mi caso, usando el control asp: Textbox (Asp.net 4.5), en lugar de configurar la página completa para validateRequest="false" utilicé 

<asp:TextBox runat="server" ID="mainTextBox"
            ValidateRequestMode="Disabled"
 ></asp:TextBox>

en el cuadro de texto que causó la excepción.

0
maozx

Una solución

No me gusta desactivar la validación posterior (validateRequest = "false"). Por otro lado, no es aceptable que la aplicación se bloquee solo porque un usuario inocente escriba <x o algo así. 

Por lo tanto, escribí una función javascript del lado del cliente (xssCheckValidates) que realiza una comprobación preliminar. Esta función se llama cuando hay un intento de publicar los datos del formulario, como este:

<form id="form1" runat="server" onsubmit="return xssCheckValidates();">

La función es bastante simple y podría mejorarse pero está haciendo su trabajo.

Tenga en cuenta que el propósito de esto no es proteger el sistema de piratería, sino proteger a los usuarios de una mala experiencia. La validación de la solicitud realizada en el servidor todavía está activada, y eso es (parte de) la protección del sistema (en la medida en que sea capaz de hacerlo). 

La razón por la que digo "parte de" aquí es porque he oído que la validación de solicitud incorporada podría no ser suficiente, por lo que podrían ser necesarios otros medios complementarios para tener una protección completa. Pero, nuevamente, la función javascript que presento aquí tiene nada que ver con la protección del sistema. Es solo destinado a garantizar que los usuarios no tengan una mala experiencia.

Puedes probarlo aquí:

    function xssCheckValidates() {
      var valid = true;
      var inp = document.querySelectorAll(
          "input:not(:disabled):not([readonly]):not([type=hidden])" +
          ",textarea:not(:disabled):not([readonly])");
      for (var i = 0; i < inp.length; i++) {
        if (!inp[i].readOnly) {
          if (inp[i].value.indexOf('<') > -1) {
            valid = false;
            break;
          }
          if (inp[i].value.indexOf('&#') > -1) {
            valid = false;
            break;
          }
        }
      }
      if (valid) {
        return true;
      } else {
        alert('In one or more of the text fields, you have typed\r\nthe character "<" or the character sequence "&#".\r\n\r\nThis is unfortunately not allowed since\r\nit can be used in hacking attempts.\r\n\r\nPlease edit the field and try again.');
        return false;
      }
    }
<form onsubmit="return xssCheckValidates();" >
  Try to type < or &# <br/>
  <input type="text" /><br/>
  <textarea></textarea>
  <input type="submit" value="Send" />
</form>

0
Magnus

Usa la Server.HtmlEncode("yourtext");

0
Voigt

Veo que hay mucho escrito sobre esto ... y no lo vi mencionado. Esto ha estado disponible desde .NET Framework 4.5

La configuración ValidateRequestMode para un control es una excelente opción. De esta manera, los otros controles de la página aún están protegidos. No es necesario realizar cambios en web.config.

 protected void Page_Load(object sender, EventArgs e)
    {
             txtMachKey.ValidateRequestMode = ValidateRequestMode.Disabled;
    }
0
Chris Catignani