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
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:
- 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)
- 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.
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.
¿No pudo el atacante simplemente solicitar el formulario para obtener un token válido? Parece bastante simple. –
@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
Gracias. ¿Qué pasa cuando el servidor está detrás de un proxy inverso y la sesión HTTP se renueva para cada solicitud? –
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
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. –
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.
- 1. Rails, OAuth y protección CSRF
- 2. Pregunta de protección CSRF
- 3. ¿Deshabilitar la protección CSRF a veces justificado?
- 4. Cómo eximir la protección CSRF en direct_to_template
- 5. ¿Para qué sirve realmente la protección CSRF?
- 6. ¿Cómo funciona la protección Rails CSRF?
- 7. Protección CSRF en solicitudes AJAX usando MVC2
- 8. Symfony 2 Desactivar la protección CSRF ficha en ajax presentar
- 9. Almacenando $ (esto) en una variable
- 10. ¿Cómo desactivo la protección CSRF en una aplicación de rieles?
- 11. ¿Es así como funciona la protección CSRF de Django?
- 12. ¿Es seguro exponer el token de protección CSRF de una sesión?
- 13. Protección de secuestro de sesión en ASP.NET
- 14. Rieles: cómo agregar protección CSRF a formularios creados en javascript?
- 15. php almacenando el ID de usuario en la sesión?
- 16. ¿Cómo puedo desactivar la protección csrf de Django solo en ciertos casos?
- 17. Diseño de API de rieles sin deshabilitar la protección de CSRF
- 18. comprensión csrf en django campo oculto en forma y CSRFCookie
- 19. Protección CSRF: ¿tenemos que generar un token para cada formulario?
- 20. Codeigniter CSRF: cómo funciona
- 21. almacenar valor en la variable de sesión y marcarlo
- 22. ¿Todavía es necesaria la etiqueta de protección {% csrf_token%} CSRF en Django 1.2?
- 23. ¿Cómo implementar la protección CSRF en llamadas Ajax usando express.js (buscando el ejemplo completo)?
- 24. Variable de sesión en la aplicación WCF
- 25. CSRF Ficha de validación: id de sesión segura?
- 26. Fichas CSRF: ¿cómo implementarlas correctamente?
- 27. PHP Almacenamiento de contraseñas con HMAC + nonce - ¿Es importante la aleatoriedad de nonce?
- 28. Rieles - Perdida de sesión con pruebas de integración y carpincho - ¿relacionado con CSRF?
- 29. Qué poner en una variable de sesión
- 30. ¿Cuál es la diferencia entre un "nonce" y un "GUID"?
¿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
@Marius: actualizaré mi respuesta para responder a su comentario. :-) –
-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