2010-02-12 15 views
10

Para protegerse contra CSRF debe poner un nonce en un campo oculto en el formulario y en una cookie o en la variable de sesión. Pero, ¿qué sucede si el usuario abre varias páginas en pestañas diferentes? En este caso, cada pestaña tendría un formulario con un nonce único, pero solo se almacenaría un nonce en la variable de sesión o cookie. O si intentas almacenar todos los nonces en la variable cookie/session, ¿cómo identificarías cuál pertenece a qué forma?Protección CSRF almacenando nonce en la variable de sesión y forma

Respuesta

6

Puede almacenar el mismo nonce en cada uno de los formularios. La forma más fácil de hacerlo es vincular el nonce a la ID de la sesión, para que esos formularios solo funcionen en esa sesión.

Deseará dificultar a los atacantes el rootear los ID de sesión y crear sus propios nonces. Entonces, una forma de hacerlo es usar HMAC-SHA256 (o similar) para ajustar el ID de la sesión, usando una clave que no expone al público.

(Obviamente, si el atacante puede obtener la propia ID de sesión, ya puede hacer el secuestro de la sesión. Así que no es de lo que estoy hablando, sino la habilidad de un atacante de crear una secuencia de comandos (que se ejecuta en computadora de la víctima) que de alguna manera se puede agarrar el identificador de sesión y usarlo para generar dinámicamente una URL con el nonce pre-llenado)


ETA:. Si el enfoque anterior es suficiente por sí solo depende de cuánto tiempo espera tus sesiones típicas durarán. Si los usuarios usualmente usan sesiones de larga duración que abarcan más de unas pocas horas, necesitarás usar algo más sofisticado.

Un enfoque es crear un nuevo nonce para cada forma, que contiene la marca de tiempo, así como hash(timestamp . sessionid) (donde hash es alguna variante de HMAC como se describe anteriormente, para prevenir la falsificación, y . es la concatenación de cadenas). A continuación, compruebe el valor de uso único por:

  1. comprobación de la marca de tiempo para asegurar que el valor de uso único es lo suficientemente fresco (esto depende de su póliza, pero unas pocas horas es típico)
  2. a continuación, calcular el hash a partir de la marca de tiempo y el ID de sesión, y comparando contra el nonce, para verificar que el valor de uso único es auténtico

Si la comprobación nonce falla, tendrá que mostrar una nueva forma, rellena previamente con la sumisión del usuario (de forma que si se tomaron un día entero para escribir su publicación, no perderán todo su trabajo duro), así como una nueva versión. Entonces el usuario puede volver a enviar de inmediato con éxito.

+0

¿Entonces no generaría un nuevo nonce cada vez? El nonce se mantendría igual durante toda la sesión y para varios envíos. – Marius

+0

@Marius: actualizaré mi respuesta para responder a su comentario. :-) –

+0

-1 No el atacante NO tiene la identificación de la sesión, el navegador sí. Este NO es un trabajo para un HMAC. – rook

2

Algunas personas generan un token para cada formulario, y ese es un enfoque muy seguro. Sin embargo, esto puede romper su aplicación y molestar a los usuarios. Para evitar todo XSRF contra su sitio, solo necesita una única variable de 1 token por sesión y luego el atacante no podrá falsificar ninguna solicitud a menos que pueda encontrar este 1 token. El problema menor con este enfoque es que el atacante podría forzar en bruto esta ficha siempre que la víctima visite un sitio web que controle el atacante. SIN EMBARGO, si el token es bastante grande, como 32 bytes más o menos, tomaría muchos años la fuerza bruta, y la sesión http debería caducar mucho antes.

+0

¿No pudo el atacante simplemente solicitar el formulario para obtener un token válido? Parece bastante simple. –

+1

@Chris Moschini no es así como funciona xsrf. Estás montando en la sesión de otra persona que no es la tuya, eso simplemente no tiene sentido. – rook

+0

Gracias. ¿Qué pasa cuando el servidor está detrás de un proxy inverso y la sesión HTTP se renueva para cada solicitud? –

0

Hace mucho tiempo, esta publicación fue escrita. Implementé un bloqueador csrf que estoy casi seguro protege bien. Funciona con múltiples ventanas abiertas, pero todavía estoy evaluando el tipo de protección que ofrece. Utiliza un enfoque DB, es decir, almacena en lugar de sesión en una tabla. NOTA: Yo uso MD5 en este caso como un mecanismo anti-sqli fácil

Pseudo Código:

FORMA:

token = randomstring #to be used in form hidden input 
db->insert into csrf (token, user_id) values (md5(token),md5(cookie(user_id)) 

- el token se mantiene entonces en el PP hasta que se ha accedido desde la escritura de la acción, a continuación:

Action script:

if md5(post(token)) belongs to md5(cookie(user_id)) 
    #discard the token 
    db -> delete from csrf where token=md5(post(token)) and user_id=md5(cookie(user_id)) 
    do the rest of the stuff 
+0

Agregar el ID de usuario al registro en realidad no agrega seguridad, pero permite eliminar los tokens no utilizados del usuario desde el archivo db al desconectarse. –

2

Lo que está describiendo ya no es un nonce (nonce = número usado una vez), es solo un identificador de sesión. El objetivo de un nonce es que solo es válido para el envío de un único formulario, por lo tanto ofrece una mayor seguridad contra el secuestro que solo un ID de sesión, pero a costa de no poder tener varias pestañas operando en paralelo en el sitio.

Nonces son excesivos para muchos propósitos. Si los usa, solo debe configurarlos y exigirlos en formularios que realizan cambios críticos en el sistema, y ​​educar a los usuarios que no pueden esperar usar más de un formulario de este tipo en paralelo. Las páginas que no configuran un nonce deben tener cuidado de no borrar ningún nonce previamente almacenado de la sesión, de modo que los usuarios aún puedan usar páginas no nonced en paralelo con un formulario nonced.

Cuestiones relacionadas