2011-06-13 14 views
5

Después de mi previous question en cuanto a si la aplicación por defecto Page.IsPostBack de ASP.net es seguro (que no es, sino que puede ser falsificada ... el verbo HTTP ni siquiera tiene que ser post!), Estaba pensando; seguramente debe haber una mejor manera de implementarlo? ¿Podemos pensar en una implementación de Page.IsPostBack que, cuando es cierta, casi garantice que la página es una devolución de datos real de ASP.net? Esto es importante si uno quiere hacer una comprobación de seguridad solo una vez (como si algún contenido va a aparecer, según las funciones del usuario), y quiere hacerlo solo si NO estamos tratando con una devolución de datos de ASP.net .¿Una implementación segura de Page.IsPostBack?

Mi primer pensamiento en cuanto a cómo hacer esto están para implementar el código de verificación en una propiedad, por lo que puede escribir algo como esto dentro de Page_Load:

if (!_isPostBack) 
{ 
    // Do security check 
    if (userIsNotAuthorized) 
    { 
     btnViewReports.Visible = false; 
     btnEditDetails.Visible = false; 
     // etc. 
    } 
} 

¿Hay una manera de poner en práctica de forma segura _isPostBack? Tal vez almacenar algo en el ViewState que sería difícil o imposible de improvisar para falsificar una devolución de datos? ¿Una cadena aleatoria?

+3

¿Está preguntando sobre "casi garantizado" en un contexto de seguridad? Eso no tiene sentido. Es seguro o no lo es. "Casi" es lo mismo que no seguro – jalf

+1

Bueno, me refiero a "casi garantizado" en el contexto de que el cifrado RSA es "casi seguro"; teóricamente puede ser forzado por fuerza bruta o puedes 'sacar suerte' y adivinar la clave de alguien, pero es increíblemente poco probable o difícil. – Jez

+0

No hay forma de que pueda confiar en cualquier cosa proveniente de un cliente. Simplemente reelabore su lógica, tiene el objeto Session. –

Respuesta

1

Bien, esto es lo que creo que es la solución: Page.IsPostBack es ya lo suficientemente seguro, siempre que la validación de eventos esté habilitada. Permítanme explicar mi razonamiento a continuación y me gustaría que alguien agregue un comentario si tengo algo mal.

Para que se publique una devolución de datos fraudulentos en ASP.net y desencadenar un evento de control OnClick, con la validación de eventos habilitada, el cliente debe enviar el campo de formulario __EVENTVALIDATION. Este campo contiene una cadena generada de manera única que básicamente le dice a ASP.net que controla un evento de devolución de datos para el que se originó esa página. Si intenta falsificar una devolución de datos para un botón que tiene el .Visibility = false configurado, verá un mensaje de error de validación de evento. Por lo tanto, parece que no se puede suplantar directamente un clic en un control oculto.

¿Qué pasa con la suplantación de una devolución de datos de uno de los botones existentes en la página que tiene renderizado (es decir, tiene permiso para ver/hacer clic en él)? Bueno, puede enviar la devolución de datos a la página, pero debe enviar un __VIEWSTATE válido o simplemente obtendrá un error de "información del estado no válida". Para tener un __VIEWSTATE válido, ya debe haber cargado la página como no devuelto, ¿verdad? Eso significa que el código de comprobación de seguridad se habrá ejecutado al menos una vez, ocultando los controles apropiados y registrándolo en el __VIEWSTATE. Por lo tanto, cuando publique la devolución de datos de la suplantación de identidad, sí, hará que Page.IsPostBack sea verdadero, pero no importa porque la __VIEWSTATE enviada ya se habrá generado en la página anterior de carga no de devolución para ocultar el contenido que no debería tener acceso a ... por lo tanto, puede falsificar una devolución de datos, pero solo pasando un __VIEWSTATE que ha sido generado previamente por una carga de página no de devolución.

Por lo tanto, debido a estos hechos, debería ser seguro colocar código de seguridad en un bloque Page.IsPostBack == false. Esto siempre debe ejecutarse una vez antes de que se pueda enviar una devolución de datos válida al servidor de ASP.net. ¿O me estoy perdiendo algo?

0

Una cookie es un mecanismo mucho mejor para sus necesidades. La cookie es un token que solo podría haber sido generado por el servidor y garantiza al titular del token ciertas afirmaciones como haber iniciado sesión recientemente y por tener ciertos permisos y/o preferencias. Algunas de estas características están integradas en FormsAuthentication. Puede implementar su propio mecanismo de cookies, pero debe investigar los protocolos de cookies seguros porque hay varias consideraciones de seguridad no obvias.

El beneficio es que no tiene que ir a la base de datos en cada solicitud, solo confíe en ello. Esta también podría ser una buena estrategia para hacer frente a ciertos ataques de DoS, ya que puede nivelar su aplicación de modo que un dispositivo dedicado frente a los servidores de su aplicación también valide los tokens y elimine las solicitudes no válidas.

Si las cookies no están permitidos, puede enviar el token como parte de la URL, como FormsAuth permite, o como un campo de formulario en su devolución de datos. Pero eso es más trabajo para administrar las cookies, en mi humilde opinión, una vez que se ha tomado la molestia de generar un token adecuado.

+0

Entonces, en ASP.net, ¿podría ser la mejor forma de hacer las cosas usar Session? Esa es la representación de ASP.net de la cookie de todos modos. – Jez

+0

[Kovacs et al. en A Secure Cookie Protocol] (http://www.cse.msu.edu/~alexliu/publications/Cookie/cookie.pdf) introduce un enfoque general aparentemente sólido para tu problema. No sé si ASP.Net FormsAuth tiene estos beneficios, pero implementé con éxito su protocolo exacto en C# hace unos años (usando las bibliotecas de cifrado .Net) sin demasiados problemas. Fue un proyecto divertido y accesible para mí y satisfactorio completarlo. No sé si ha habido críticas o mejoras relevantes en su trabajo. –

2

Hace un par de años tuve un proyecto en el que hicimos algunas pruebas de penetración en el código. Marcaron el hecho de que por defecto IsPostback no verifica el verbo http. Para hacer frente a esta creé una clase Página abstracto con su propia implementación de IsPostback que ensombrece la implmentation defecto:

Public Class ProjectPage : System.Web.UI.Page 

    public new bool IsPostBack() 
    { 
     return (Page.IsPostBack && Request.HttpMethod.ToUpper() == "POST"); 
    } 

End Class 

Esto le permite hacer pruebas en el verbo HTTP, pero se puede ampliar fácilmente el método de hacer otra cheques también.

Cuestiones relacionadas