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

1471

Cada vez que un usuario publica algo que contiene <o está >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 carácter 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 me parece lo suficientemente profesional.

Deshabilitar 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 devolución que contiene caracteres restringidos en HTML, ese valor publicado en la colección de formularios se codificará automáticamente en HTML. Entonces la .Textpropiedad de mi cuadro de texto serásomething & lt; html & gt;

¿Hay alguna manera de hacer esto desde un controlador?

Radu094
fuente
68
Tenga en cuenta que puede obtener este error si también tiene nombres de entidad HTML (& amp;) o números de entidad (& # 39;) en su entrada.
Drew Noakes el
18
Bueno, dado que es mi pregunta, creo que puedo definir cuál es el punto: bloquear un proceso de solicitud completo y devolver un mensaje de error genérico porque alguien escribió un '<' es excesivo. Sobre todo porque sabes que la mayoría de las personas simplemente 'validateRequest = false' para deshacerse de él,
reabriendo
77
@DrewNoakes: los nombres de entidad (& amp;) no parecen ser un problema según mis pruebas (probadas en .Net 4.0), aunque los números de entidad (& # 39;) no validan (como usted dijo). Si desmonta el método System.Web.CrossSiteScriptingValidation.IsDangerousString usando .Net Reflector, verá que el código busca específicamente etiquetas html (comenzando con <) y números de entidad (comenzando con & #)
Gyum Fox
55
Cree un nuevo sitio en VS2014 utilizando el proyecto MVC predeterminado y ejecútelo. Haga clic en el enlace de registro, agregue cualquier correo electrónico y use "<P455-0r [!" como la contraseña El mismo error fuera de la caja, no tratando de hacer nada malicioso, el campo de contraseña no se mostrará, por lo que no será un ataque XSS, pero la única forma de solucionarlo es eliminar por completo la validación con ValidateInput (falso) ? La sugerencia AllowHtml no funciona en esta situación, todavía explotó con el mismo error. Se detectó un valor Request.Form potencialmente peligroso del cliente (Contraseña = "<P455-0r [!").
stephenbayer
TL; DR puesto <httpRuntime requestValidationMode="2.0" />en web.config

Respuestas:

1081

Creo que lo estás atacando desde el ángulo equivocado al tratar de 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, las 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 comillas simples, 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 puede filtrar la entrada aleatoria de caracteres peligrosos, porque cualquier carácter puede ser peligroso en las circunstancias correctas. Debe codificar en el punto donde algunos caracteres específicos pueden volverse peligrosos porque se cruzan a un sub-idioma diferente donde tienen un significado especial. Cuando escribe una cadena en HTML, debe codificar caracteres que tengan un significado especial en HTML, utilizando Server.HtmlEncode. Si pasa una cadena a una declaración SQL dinámica, debe codificar diferentes caracteres (o mejor, deje que el marco lo haga por usted usando declaraciones preparadas o similares).

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

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

JacquesB
fuente
74
Para aquellos que llegan tarde: validateRequest = "false" va en la directiva de la página (primera línea de su archivo .aspx)
MGOwen
56
Consejo: coloque <httpRuntime requestValidationMode="2.0" />una etiqueta de ubicación para evitar matar la útil protección proporcionada por la validación del resto de su sitio.
Brian
299
En MVC3, esto está [AllowHtml]en la propiedad del modelo.
Jeremy Holovacs
2
Para deshabilitarlo globalmente para MVC 3 también necesita GlobalFilters.Filters.Add(new ValidateInputAttribute(false));en Application_Start().
Alex
15
@ MGOwen también puede agregar la directiva de página a web.config a través de <pages validateRequest="false" />in <system.web />. Al hacerlo, se aplicará la propiedad a todas las páginas.
oliver-clare
504

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

Muestra de C #:

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

Muestra de Visual Basic:

<AcceptVerbs(HttpVerbs.Post), ValidateInput(False)> _
Function Edit(ByVal collection As FormCollection) As ActionResult
    ...
End Function
Zack Peterson
fuente
el problema puede surgir cuando se necesita en una página de la aplicación completa
3
También puede agregar el atributo [ValidateInput (false)] en el nivel de clase. Si lo agrega a su clase de controlador base, se aplicará a todas las acciones del método del controlador.
Shan Plourde
@Zack Gracias por la solución. Por otro lado, me pregunto si [AllowHtml]es mejor que ValidateInput(false), porque [AllowHtml]se define a la vez para una propiedad, es decir, el campo Editor y cada vez que se usa no hay necesidad de usarlo para varias acciones. ¿Que sugieres?
Jack
@Zack Peterson ¿Es seguro de usar? No hay problema de seguridad?
shrey Pav
417

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

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

[AllowHtml]
public string Description { get; set; }
Anthony Johnston
fuente
12
¡Mucho mejor hacer esto declarativamente que en el controlador!
Andiih
29
La única respuesta correcta! deshabilitar la validación en la acción del controlador es hacky. Y para deshabilitar la validación a nivel de aplicación, los desarrolladores deben ser colgados.
trailmax
¿Esto desapareció en MVC 4?
granadaCoder
1
¿Cuál es la diferencia entre ValidateInput(false)y AllowHtml? ¿Cuál es la ventaja de uno sobre el otro? ¿Cuándo me gustaría usar en AllowHtmllugar de ValidateInput(false)? ¿Cuándo me gustaría usar ValidateInput(false)más AllowHtml? ¿Cuándo querría usar ambos? ¿Tiene sentido usar ambos?
Ian Boyd
3
ValidateInput está en el método, AllowHtml está en la propiedad del modelo, por lo que solo permite el que espera tener html, no todos
Anthony Johnston
213

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

<httpRuntime requestValidationMode="2.0" />

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

requestValidationMode="2.0"

Puede deshabilitar la validación completa de la solicitud especificando:

validateRequest="false"
JordanC
fuente
30
Dentro de las <system.web>etiquetas.
Hosam Aly el
8
He puesto esto en web.config, pero aún con el error "Un valor de Solicitud.Formulario potencialmente peligroso"
Filip
20
Parece que <httpRuntime requestValidationMode = "2.0" /> funciona solo cuando 2.0 framework está instalado en la máquina. ¿Qué pasa si 2.0 framework no está instalado pero solo 4.0 framework está instalado?
Samuel
Esto funcionó totalmente para mí. ¡Ninguno de los pasos del documento en las otras respuestas fue necesario (incluyendo validateRequest = "false")!
Tom Redfern
112

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 <location>elemento. 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 páginas donde la validación de solicitud está deshabilitada.

Carter Medlin
fuente
Más información sobre requestValidationMode = 2 | 4 aquí: msdn.microsoft.com/en-us/library/…
GlennG
Lamentablemente, esto no funcionará con ASP.net 2.0 como está. Elimine la línea httpRuntime y funcionará.
Fandango68
Agregué una advertencia que recuerda a las personas que validen manualmente la entrada cuando la validación está deshabilitada.
Carter Medlin
72

Las respuestas anteriores son geniales, pero nadie dijo cómo excluir un solo campo de ser validado para inyecciones 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 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 "Se detectó un valor de Solicitud potencialmente peligroso.

Lo he usado 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.

gligoran
fuente
10
Lamentablemente, parece que la función Excluir se eliminó de MVC 3 RTW :(
Matt Greer
2
Tampoco fue incluido en MVC 4
wilsjd
99
Úselo [AllowHtml]en las propiedades del modelo en lugar de [ValidateInput]en la Acción para lograr el mismo resultado final.
Mrchief
2
@ Christof Tenga en cuenta que mi respuesta tiene 5 años. No he encontrado este problema en mucho tiempo, por lo que podría haber muchas mejores formas de abordarlo. Con respecto a estas dos opciones, creo que depende de su situación. Tal vez exponga ese modelo en más de una acción y en algunos lugares HTML está permitido o no. En tal caso [AllowHtml]no es una opción. Recomiendo revisar este artículo: weblogs.asp.net/imranbaloch/… , pero también es algo antiguo y puede estar desactualizado.
gligoran
1
Todavía hay una manera de excluir parámetros de métodos particulares de la validación, consulte mi respuesta aquí: stackoverflow.com/a/50796666/56621
Alex
51

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

<httpRuntime requestValidationMode="2.0"/>

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

y

[Post, ValidateInput(false)]
public ActionResult Edit(string message) {
    ...
}
ranthonissen
fuente
2
Para mí, validateRequest="false"no era necesario, solorequestValidationMode="2.0"
tom redfern
requestValidationMode = "2.0" aún genera el error con datos codificados en HTML. No hay solución excepto que base64 codifique todo y luego lo envíe.
MC9000
48

Puede codificar HTML en el contenido del cuadro de texto, pero desafortunadamente eso no detendrá la excepción. En mi experiencia, no hay forma de evitarlo, y debe deshabilitar la validación de la página. Al hacerlo, estás diciendo: "Tendré cuidado, lo prometo".

Pavel Chuchuva
fuente
43

Para MVC, ignore la validación de entrada agregando

[ValidateInput (falso)]

sobre cada acción en el controlador.

A.Dara
fuente
Esto no parece funcionar en el caso de que llegue al método del controlador a través de una ruta configurada.
PandaWood
En realidad, la explicación técnica es que esto solo funciona cuando el personaje infractor está en la "cadena de consulta" ... si está en la ruta de solicitud, el atributo de Validación no funciona
PandaWood
42

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

BenMaddox
fuente
40

La respuesta a esta pregunta es simple:

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

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

flakomalo
fuente
1
Solo aplicable para ASP.NET 4.5 (y, presumiblemente, lo que sea que venga después). Pre 4.5 no es compatible con esto.
Beska
3
Desearía poder subir de esta manera. Estoy usando .NET 4.5 y esto es exactamente lo que necesitaba ya que no estoy usando MVC y no puedo cambiar el web.config.
Chris Gillum
1
Sí, pero ¿y si estás usando .Net 2? Algunos de nosotros no tenemos otra opción
Fandango68
esto obtiene parámetros POST o GET?
max4ever
¿Estás diciendo que esto evita una excepción que ya se lanzó? ¿O .net 4.5 retrasa la excepción y la validación hasta que los datos se leen realmente del Request?
ebyrob
34

Tenga en cuenta que algunos controles .NET codificarán automáticamente la salida HTML. Por ejemplo, establecer la propiedad .Text en un control TextBox la 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 envolverá Server.HtmlEncode (); todo lo que se establece 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.

Experimente un poco para ver qué se codifica y qué no.

Peter Mortensen
fuente
29

En el archivo web.config, dentro de las etiquetas, inserte el elemento httpRuntime con el atributo requestValidationMode = "2.0". Agregue también el atributo validateRequest = "false" en el elemento de páginas.

Ejemplo:

<configuration>
  <system.web>
   <httpRuntime requestValidationMode="2.0" />
  </system.web>
  <pages validateRequest="false">
  </pages>
</configuration>
Mahdi jokar
fuente
1
Para mí, validateRequest = "false" no era necesario, solo requestValidationMode = "2.0"
tom redfern
3
La sección "páginas" debe estar dentro de la sección "system.web".
Carter Medlin
respuesta peligrosa, una vez más.
MC9000
Yo necesitaba los dos. Gracias
Jack
23

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 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);")
Peter Mortensen
fuente
44
Esto seguirá dejando a la aplicación vulnerable a las solicitudes POST inventadas. Un usuario normal tendrá problemas para ingresar caracteres como: o comillas, pero un hacker habitual no tendrá problemas para PUBLICAR datos con formato incorrecto en el servidor. Vodear esto muuuy abajo.
Radu094
13
@ Radu094: esta solución le permite mantener ValidateRequest = true, lo que significa que los piratas informáticos seguirán golpeando ese muro. Vote hacia arriba, ya que esto lo deja menos vulnerable que desactivar ValidateRequest.
jbehren
21

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

<%@ 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.

Piercy
fuente
Funciona para formularios web c # o VB
TheAlbear
19

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;
    }
}
Sel
fuente
¡Agradable! No tenía conocimiento de la capacidad de reemplazar el Validador de solicitudes. En lugar de decir "ok" como tú, extendí esta idea para no validar los campos que terminan en "_NoValidation" como su nombre. Código a continuación.
Walden Leverich
Walden Leverich, para hacer esto, vea [AllowHtml] attribure
Sel
Sel, sí, en un entorno MVC que funcionaría. Pero en una aplicación de formularios web no tengo un modelo para hacerlo. :-)
Walden Leverich
15

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

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

Si está utilizando Framework 4.5, entonces 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 como esta:

<%@ Page EnableEventValidation="false" %>

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

Recomiendo no hacerlo.

Durgesh Pandey
fuente
13

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

Supongo que podrías hacerlo en un módulo; pero eso deja abiertas algunas preguntas; ¿Qué pasa si desea guardar la entrada en una base de datos? De repente, debido a que está guardando datos codificados en la base de datos, termina confiando en la entrada, lo que probablemente sea una mala idea. Lo ideal es que almacene 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 la biblioteca Anti-XSS más nueva y más completa del equipo de Microsoft ACE.

soplar el dardo
fuente
12

Porque

ASP.NET por defecto valida todos los controles de entrada para contenido potencialmente inseguro que puede conducir a secuencias de comandos entre sitios (XSS) e inyecciones SQL . Por lo tanto, no permite dicho contenido lanzando la excepción anterior. Por defecto, 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 @Pagedirectiva en false.

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

Esto deshabilitará la validación de solicitudes para la página en la que ha establecido el indicador ValidateRequest en falso. Si desea desactivar esto, verifique en toda su aplicación web; deberá configurarlo como falso en su sección web.config <system.web>

<pages validateRequest ="false" />

Para marcos .NET 4.0 o superior, 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: ASP.Net Error: Se detectó un valor de Request.Form potencialmente peligroso desde el cliente

vakeel
fuente
10

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

<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 la 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 pirata informático intenta publicar sin saltarse JavaScript, solo verá el error. También puede guardar todos estos datos codificados en una base de datos, luego dejarlos de lado (en el lado del servidor) y analizar y verificar si hay ataques antes de mostrarlos en otro lugar.

Jason Shuler
fuente
Esta es una buena solución. Es una forma manual adecuada de controlarlo usted mismo y no invalidar todo el sitio web o la página
Fandango68
Asegúrese de usar un marcado HTML, no un control ASP.Net (es decir, no runat = "server") para el área de texto, luego use el control oculto ASP.Net para lo oculto. Esta es la mejor solución que he visto sin comprometer nada. Naturalmente, desea analizar sus datos para XSS, inyección de SQL en el lado del servidor, pero al menos puede publicar HTML
MC9000
escape(...)puede tomar mucho tiempo En mi caso, el marcado era un archivo XML completo (2 MB). Usted puede preguntar: "¿Por qué no solo usas <input type="file"...y ... estoy de acuerdo contigo? :)
The Red Pea
10

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

Si, como yo, desea desactivar esta función (en mi humilde opinión, bastante inútil) en todo el sitio, puede anular el método Execute () en su controlador base (si aún no tiene un controlador base, le sugiero que cree 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úrese de que está codificando HTML todo lo que se bombea a las vistas que provienen de la entrada del usuario (de todos modos, es un comportamiento predeterminado en ASP.NET MVC 3 con Razor, por lo que a menos que por alguna extraña razón esté usando Html.Raw () usted No debería requerir esta función.

magritte
fuente
9

También recibí este error.

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

Paso el nombre del rol a un método para otorgar a los Usuarios a ese rol y la $.ajaxsolicitud de publicación fallaba miserablemente ...

Hice esto para resolver el problema:

En vez 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". &#225;ASP.NET MVC estaba bloqueando este valor con la entidad HTML . Ahora obtengo el roleNamevalor del parámetro como debería ser: roleName="Cadastro Básico"y el motor ASP.NET MVC ya no bloqueará la solicitud.

Leniel Maccaferri
fuente
9

Desactivar la validación de la página si realmente necesita los caracteres especiales como, >,, <, etc A continuación, asegúrese de que cuando se muestra la entrada del usuario, los datos son codificados en HTML.

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

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

lanudo
fuente
El enlace está roto.
Peter Mortensen
7

También puede usar la función de escape (cadena) de JavaScript para reemplazar los caracteres especiales. Luego, del lado del servidor, use el servidor. 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.

Trisped
fuente
7

Terminé usando JavaScript antes de cada devolución de datos 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;
}

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

Ryan
fuente
Debe haber corchetes grandes en lugar de corchetes pequeños. Como `if (tbs [i] .type == 'text') {` en lugar de `if (tbs (i) .type == 'text') {`
Shilpa Soni
5

Puedes usar algo como:

var nvc = Request.Unvalidated().Form;

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

Ady Levy
fuente
Gracias, su respuesta me ahorró mucho tiempo
habib
4

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

Paweł Hajdan
fuente
4

Si solo desea decirles a sus usuarios que <y> no se deben usar PERO, no desea que se procese / regrese todo el formulario (y pierda toda la información) de antemano, ¿no podría simplemente ingresar un validador alrededor del campo para detectar esos (y tal vez otros personajes potencialmente peligrosos)?

Capitán Sapo
fuente
post dijo "validador" por favor
mxmissile
4

Ninguna de las sugerencias funcionó para mí. De todos modos, no quería desactivar esta función para todo el sitio web 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 detrás y la inserto en mi base de datos.

Mike S.
fuente