2008-10-13 12 views
11

Entonces, ¿cuál es la mejor manera de prevenir un ataque XSRF para una aplicación GAE? Imagine lo siguiente:¿Cómo prevenir mejor los ataques de CSRF en una aplicación GAE?

  1. Cualquiera puede ver el objeto público de un usuario, y el id. De db.Model se utiliza en la solicitud para determinar qué objeto mostrar. El usuario malintencionado ahora tiene la identificación.
  2. El usuario malintencionado crea su propio objeto y comprueba el formulario de eliminación. Ahora saben cómo eliminar un objeto con una determinada identificación.
  3. El usuario malintencionado consigue que un usuario inocente envíe una solicitud de eliminación para el objeto de ese usuario.

¿Qué pasos puedo agregar para evitar el # 3? Tenga en cuenta que cuando digo ID, estoy usando la parte de ID real de la clave. Una idea que tuve fue usar el valor de la clave completa en las solicitudes de eliminación, pero ¿evitaría que un usuario malintencionado pueda resolver esto? Hasta donde yo sé, la clave es una combinación del tipo de clase de modelo, el id de la aplicación y el ID de la instancia del objeto, por lo que probablemente podrían derivar la clave del ID si así lo desean.

¿Alguna otra idea? Jeff escribió a post about this, y sugirió un par de métodos: un valor de formulario oculto que cambiaría en cada solicitud y un valor de cookie escrito mediante js en el formulario. No querré excluir usuarios que no sean javascript, por lo que la solución de cookies no sirve; para el valor de formulario oculto, tendría que hacer una escritura en el almacén de datos en cada solicitud que mostrara un objeto eliminable, no una situación ideal para una escalabilidad aplicación!

¿Alguna otra idea por ahí?

Respuesta

11

Cuando genera la página que permite al usuario eliminar un objeto, genere un token aleatorio e inclúyalo en un campo de formulario oculto. Establezca también una cookie HTTP solo con ese valor. Cuando reciba una solicitud de eliminación, verifique que el token aleatorio del formulario y el valor de la coincidencia de cookie.

Su token aleatorio no debe ser simplemente un número aleatorio. Debe encriptar la combinación de un número aleatorio y la identidad del usuario, para que a los atacantes les resulte difícil falsificar sus propios tokens. También debe usar diferentes claves de encriptación para el valor almacenado en el formulario y el valor almacenado en la cookie, de modo que si uno de los tokens tiene una fuga, aún es difícil para un atacante falsificar el otro token.

Este enfoque verifica que la solicitud de eliminación se origina en su formulario, por la presencia del token de seguridad en el formulario; y no requiere escribir en el almacén de datos.

Este enfoque sigue siendo vulnerable a los ataques de secuencias de comandos entre sitios, donde un atacante podría recuperar el valor oculto del formulario o enviar el formulario, así que pruebe su sitio para detectar vulnerabilidades de scripts entre sitios. Este enfoque también es vulnerable a los ataques "clickjacking".

+0

También me gusta el enfoque de Macbirdie, pero me gusta que esto proporcione una seguridad razonable sin almacenamiento en el lado del servidor. –

5

Simple: Compruebe el referer. Es (deliberadamente) imposible configurar esto usando Javascript, formularios HTML, etc. Si está en blanco (algunos proxies y navegadores eliminan los referers) o desde su propio sitio, o más específicamente desde la fuente esperada, se lo permite. De lo contrario, denegarlo y registrarlo.

Editar: Jeff escribió un followup article con un par de maneras de prevenir los ataques de CSRF.

+0

Entonces, si alguien se conecta a mi sitio a través de un proxy, y se encuentra con un ataque XSRF, estarían desprotegidos? Además, Jeff mencionó que las referencias son fáciles de falsificar. Sé que como usuario puedo hacerlo fácilmente, pero ¿podría un sitio de alguna manera hacer que el navegador informara una referencia diferente? –

+0

Solo estarían desprotegidos si su proxy o navegador elimina al receptor. Muy pocos hacen esto, y al proteger a todas las personas que puedes proteger, haces que el ataque no sea atractivo. Y sí, los referers son falsificables, pero no por ningún código que un atacante pueda persuadir a un usuario para que lo ejecute en su navegador. –

+1

¡No permita encabezados de Referer en blanco! Si se solicita una página HTTP desde una página HTTPS, el [Referer no se envía] (http://stackoverflow.com/a/1361720/691281). Por lo tanto, si su formulario se encuentra en una página HTTP, un atacante puede hacer trivialmente que el Referer quede en blanco en un ataque CSRF. Incluso si su formulario está en una página HTTPS, sospecho mucho de los encabezados de Referer en blanco. –

4

En la respuesta del servidor que muestra el formulario crea un hash mágico (basado en el cliente ip + fecha/hora + sal aleatoria, lo que sea). Póngalo en una cookie y almacénelo en algún lugar del servidor. Durante la gestión de acciones de envío, compruebe el hash de cookies en la entrada de la base de datos.

Si no hay tal hash o es diferente, rechace la presentación.

Después del envío exitoso, puede eliminar la entrada de hash, cambiar su estado para enviarlo, lo que más le convenga.

Ese método debería protegerlo en muchos casos, pero seguramente todavía no es 100% a prueba de balas.

Haga una búsqueda de artículos en CSRF, tal vez encontrará algunas buenas respuestas en este Stack Overflow cosa. ;)

No realice comprobaciones de referencia o validaciones de IP del cliente: es demasiado propenso a errores (la información de referencia puede ser borrada por el agente de usuario, un proxy o por preferencias del usuario) y la IP del cliente puede cambiar entre el formulario creación y envío: no castigue al usuario por la asignación dinámica de direcciones IP.

+0

En el motor de aplicaciones, ¿no se requiere una escritura en el almacén de datos cada vez que visualizo la opción para eliminar? Estoy receloso de hacer esto, ya que hay una opción de eliminación en casi todas las páginas que visitará un usuario. –

+1

Sí, podría generar una escritura en cada pantalla de página, pero en realidad no tiene que ser así. Si las transiciones de hash ocurren muy a menudo, puedes almacenarlas en Memcache, a menos que tu sitio tenga una carga muy grande, por supuesto. Otra opción es generar el hash solo si el usuario golpea el botón "eliminar" de forma asincrónica. Sin embargo, esto debe estar bien pensado, ya que pueden surgir nuevos problemas de seguridad. – macbirdie

Cuestiones relacionadas