name - csrf token django
GeneraciĆ³n de tokens CSRF (8)
CSRF utiliza la sesión del usuario, por lo tanto, si no tiene una, no hay CSRF.
Esta es una pregunta sobre la generación de tokens CSRF.
Por lo general, me gustaría generar un token basado en una pieza única de datos asociada a la sesión del usuario, y hash y salado con una clave secreta.
Mi pregunta es respecto a la generación de tokens cuando NO HAY datos únicos de usuario para usar. No hay sesiones disponibles, las cookies no son una opción, la dirección IP y cosas de esa naturaleza no son confiables.
¿Hay alguna razón por la cual no puedo incluir la cadena al hash como parte de la solicitud también? Ejemplo de pseudocódigo para generar el token e incrustarlo:
var $stringToHash = random()
var $csrfToken = hash($stringToHash + $mySecretKey)
<a href="http://foo.com?csrfToken={$csrfToken}&key={$stringToHash}">click me</a>
Ejemplo de validación del lado del servidor del token CSRF
var $stringToHash = request.get(''key'')
var $isValidToken = hash($stringToHash + $mySecrtKey) == request.get(''csrfToken'')
La cadena que se usa en el hash sería diferente en cada solicitud. Siempre que se incluya en cada solicitud, la validación del token CSRF podría continuar. Dado que es nuevo en cada solicitud y solo está incrustado en la página, el acceso externo al token no estaría disponible. La seguridad del token cae en $ mySecretKey, que solo yo conozco.
¿Es esto un enfoque ingenuo? ¿Me estoy perdiendo alguna razón por la que esto no puede funcionar?
Gracias
Creo que la mejor idea es hacer hash basado en HMAC, es decir, hacer hash cifrado por alguna contraseña en esta secuencia: username + user_id + timestamp. Cada solicitud del hash debe ser diferente, la marca de tiempo debe ser si no desea obtener una repetición simple del hash en ataque.
El token CSRF está destinado a evitar modificaciones de datos (no intencionales), que generalmente se aplican a solicitudes POST.
Por lo tanto, debe incluir token CSRF para cada solicitud que cambie los datos (solicitud GET o POST).
Mi pregunta es respecto a la generación de tokens cuando NO HAY datos únicos de usuario para usar. No hay sesiones disponibles, las cookies no son una opción, la dirección IP y cosas de esa naturaleza no son confiables.
Luego simplemente cree una identificación de usuario única para cada visitante. Incluya esa identificación en una cookie o en las URL (si las cookies están deshabilitadas).
Editar:
Considera el siguiente evento:
Ha iniciado sesión en su cuenta de Facebook y luego ingresado a algún sitio web arbitrario.
En ese sitio web hay un formulario que envía, que le dice a su navegador que envíe una solicitud POST a su cuenta de Facebook.
Esa solicitud POST puede cambiar su contraseña o agregar un comentario, etc., porque la aplicación de Facebook lo reconoció como un usuario registrado y registrado. (a menos que haya otro mecanismo de bloqueo, como CAPTCHA)
Hay una implementación múltiple de token CSRF. La clave es si este token csrf se genera en el lado del cliente o del servidor. Debido a que la implementación cambia drásticamente para estos dos escenarios y la entropía del token también.
Por el lado del servidor, SecureRandom es la forma preferida, pero en su caso usted desea generar el token CSRF antes de que se identifique a cualquier usuario, window.crypto proporciona esta funcionalidad donde puede generar una cadena lo suficientemente indescifrable para ser utilizada para el token CSRF.
Pruebe base64_encode(openssl_random_pseudo_bytes(16))
. https://github.com/codeguy/php-the-right-way/issues/272#issuecomment-18688498 y lo usé para mi ejemplo de formulario en https://gist.github.com/mikaelz/5668195
Quiero decir que su enfoque funciona, porque el ataque CSRF es el atacante que utiliza el navegador de la víctima para forjar un estado de inicio de sesión, ¿por qué pueden hacerlo? porque en la mayoría de los servidores, la verificación de la sesión se basa en un ID de sesión en la cookie, y la cookie es un dato que se adjuntará automáticamente a una solicitud HTTP enviada al servidor.
Por lo tanto, hay dos factores clave para defender CSRF
- Genere un token de desafío y solicite que el cliente lo pase al servidor de una manera que no sea de cookie, ya sea que el param de URL o el formulario POST estén correctos.
- Mantenga el token seguro como lo que hizo con el SessionID, por ejemplo, usando SSL.
Recomiendo leer CSRF Prevention Cheat Sheet
Simplemente necesita el mismo "token" en la URL / formulario y en la cookie. Esto significa que puede hacer que su página configure la cookie token a lo que quiera (preferiblemente algún valor aleatorio) mediante JavaScript y luego simplemente pase el mismo valor en todas las solicitudes que va a su servidor (como un param o un formulario URI). campo). No es necesario que su servidor genere la cookie.
Esto es seguro siempre que confiemos en que el navegador no permite que las páginas de un dominio editen / lean las cookies de otros dominios, y se supone que hoy es bastante seguro.
El hecho de que el servidor genere el token supondrá que este token se puede transmitir de forma segura a su navegador sin que lo retome ningún intento de CSRF (¿por qué correr el riesgo?). Aunque podría poner más lógica en un token generado por el servidor, pero para evitar CSRF no es necesario.
(Si me equivoco aquí, por favor avíseme)
¿Hay alguna razón por la cual no puedo incluir la cadena al hash como parte de la solicitud también?
Los tokens CSRF tienen dos partes. El token incrustado en el formulario y un token correspondiente en otro lugar, ya sea en una cookie, almacenado en una sesión o en otro lugar. Este uso de otra parte impide que una página sea independiente.
Si incluye la cadena al hash en la solicitud, entonces la solicitud es independiente, por lo que copiar el formulario es todo lo que un atacante debe hacer, ya que tienen ambas partes del token y, por lo tanto, no hay protección.
Incluso ponerlo en el formulario URL significa que es autocontenido, el atacante simplemente copia el formulario y la URL de envío.