2012-07-06 14 views
5

Similar a this question pero no me importa tanto qué caracteres provocarán/no provocarán el error. Tengo más curiosidad sobre a qué método puedo llamar, para comprobarlo por mí mismo, si la cadena actual activará el mensaje de error anterior.Cómo comprobar si la cadena se activará "Se detectó un valor Request.Form potencialmente peligroso ..." error

Para dar un poco de antecedentes, estoy creando contraseñas aleatorias cuando un usuario se olvida de las suyas y necesita un restablecimiento. Desafortunadamente, el generador de contraseñas aleatorias "accidentalmente" creó uno con &# recientemente. Esto causó que la página se rompiera cuando el usuario intentó iniciar sesión con ella.

Como se menciona en muchas publicaciones sobre este tema, ValidateRequest=false (o <httpRuntime requestValidationMode="2.0" /> para .NET 4.0) se puede utilizar para desactivar la comprobación de .NET de estos exploits, pero no veo ninguna razón para perder esta capa adicional de seguridad cuando yo soy el que está creando la cuerda en primer lugar. Y simplemente decirle al generador aleatorio que vuelva a aleatorizar en una lista incompleta (<, &#, etc.) no parece ser la solución más limpia, así que me gustaría utilizar el mismo método para verificar que .NET está usando.

Explicación de Microsoft de qué exploits están en cuestión y qué se está haciendo para protegerse de ellos here.

This guy habla de encontrar una función llamada IsDangerousString después de indagar con Reflector, pero no puedo encontrar esta función para usarla. También se está refiriendo a .NET 1.1 y estoy trabajando con .NET 3.5

+0

una pregunta interesante, pero no veo una razón por las que se incluyen personajes tan oscuros. Probablemente usaría la clase RandomNumberGenerator para llenar un byte [] y luego usaría un codificador z-base32 para codificar los bytes en una cadena. – Shelakel

+2

conoce el carácter "explotar" que desea permitir, ¿por qué no HTML? Codifíquelos antes de publicarlos y, a continuación, descodifíquelos en html – HatSoft

+0

@Shelakel Claro, hay muchas otras maneras de generar contraseñas aleatorias. Desafortunadamente, sin embargo, estamos estancados al tener que cumplir con las 4 reglas de 4 caracteres (minúsculas, mayúsculas, números, caracteres especiales) con contraseñas para este proyecto. Por supuesto, podría eliminar los caracteres "oscuros" ofensivos, pero como la especificación no es muy clara, me gustaría usar la misma función que el sistema debe verificar. – Mercurybullet

Respuesta

5

La clase ASP.NET que valida las solicitudes es System.Web.CrossSiteScriptingValidation, y el método que desea es IsDangerousString. Desafortunadamente, ambos están marcados internal, por lo que no puede acceder a ellos directamente. Tiene varias opciones:

Opción 1: Llamar IsDangerousString a través de Reflection. Sin embargo, Microsoft podría cambiar el método en cualquier momento, lo que rompería su solicitud.

Opción 2: Descompila IsDangerousString y cópialo en tu propia aplicación. Vea el código a continuación.

Opción 3: Llamada Membership.GeneratePassword. Esto devuelve una contraseña que garantiza la aprobación de la validación de la solicitud.

Extractos de la clase ASP.NET CrossSiteScriptingValidation (a través de .NET Reflector):

private static char[] startingChars = new char[] { '<', '&' }; 

internal static bool IsDangerousString(string s, out int matchIndex) 
{ 
    matchIndex = 0; 
    int startIndex = 0; 
    while (true) 
    { 
     int num2 = s.IndexOfAny(startingChars, startIndex); 
     if (num2 < 0) 
     { 
      return false; 
     } 
     if (num2 == (s.Length - 1)) 
     { 
      return false; 
     } 
     matchIndex = num2; 
     char ch = s[num2]; 
     if (ch != '&') 
     { 
      if ((ch == '<') && ((IsAtoZ(s[num2 + 1]) || (s[num2 + 1] == '!')) || ((s[num2 + 1] == '/') || (s[num2 + 1] == '?')))) 
      { 
       return true; 
      } 
     } 
     else if (s[num2 + 1] == '#') 
     { 
      return true; 
     } 
     startIndex = num2 + 1; 
    } 
} 

private static bool IsAtoZ(char c) 
{ 
    return (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))); 
} 
+3

Gracias por la información.Dado que la función es interna y no podré acceder directamente a ella para las actualizaciones, ¿hay alguna razón para no usar simplemente la siguiente expresión regular (con ignoreCase)? '\ <[a-z! /?] | & #' – Mercurybullet

+0

La expresión regular es equivalente a la Opción 2, solo que es mucho más conciso. :-) Esto es probablemente lo mejor que puedes hacer por ahora. Sin embargo, en la próxima versión de ASP.NET, podrá omitir la validación de ciertos campos utilizando [HttpRequest.Unvalidated] (http://msdn.microsoft.com/en-us/library/system.web Propiedad .httprequest.unvalidated (v = VS.110) .aspx). –

Cuestiones relacionadas