[pyar] Si actualizan a Django 1.7.3 y los usuarios no pueden iniciar sesión, lean esto

Horacio G. de Oro info en data-tsunami.com
Mie Ene 14 21:50:43 ART 2015


Buenas! Hoy vi que salio Django 1.7.3 con algunos parches relacionados
con problemas de seguridad, asi que luego de revisar la infor y ver
que no cambio nada, hice el clasico "branch ultimo deploy + aplicar
cambio en requeriments.txt  + deploy con asible + merge branch en
master". En unos minutos ya tenia Django actualizado.

Y luego de eso, nadie pudo inicar sesión. Asi que "git revert y deploy
urgente", y a investigar que estaba pansando...

Resulta que como parte de la actualizacion, cambiaron un parámetro del
componente que realiza el "hasheo" y verificación del password:

https://github.com/django/django/commit/4aed731154b12e2948ee2b6a8baa5083840a343b#diff-2f01db46550174ad3e55be7070b98ec9R230

Este nuevo valor mejora la calidad de los hashes, y al autenticar un
usuario, Django detecta que hay nuevos parametros, y re-genera el hash
del password para que sea guardado en la BD con la mejoras
introducidas por los nuevos parametros. Hermoso! (OJO, el password
introducido por el usuario es el mismo, solo el hash cambia)

Por ejemplo, en la tabla de usuarios yo tenía este hash:
"pbkdf2_sha256$12000$xxxxxxxxxx". El '12000' es el parámetro del
hasher con el que fue creado el password. En Django 1.7.3 fue cambiado
a '15000', y por lo tanto, con mi mismo password, ahora el hash se
diferente: "pbkdf2_sha256$15000$yyyyyyyyyyy"

A esto le sumamos
https://docs.djangoproject.com/en/1.7/topics/auth/default/#session-invalidation-on-password-change.
Esta característica de Django fue hecha para que, si alguien cambia el
password, las sesiones abiertas que existan iniciadas con el password
viejo sean tomadas como inválidas, y forzamos que se re-ingrese el
password. Está bueno: te olvidaste una sesión abierta en alguna PC, y
ésta sesión se invalida al cambiar el password.

El resultado de todo esto es que el middleware toma a la actualización
del hash como si fuera un cambio de password, y el usuario que se
estaba autenticando, es des-autenticado!

Encontré 2 soluciones:

1) el usuario devuelto por authenticate() tiene el password nuevo. Si
hacemos un save(), el middleware no detectará diferencia, y todo
andará.

2) crear un hasher customizado, que solo sobreescriba el valor de
"iterations": https://gist.github.com/hgdeoro/1b27610736bd64c35535

3) la tercera que se me ocurre, que no he investigado, es usar
"update_session_auth_hash()", pero no estoy seguro si funcionaría, ni
si siquiera tiene sentido
https://docs.djangoproject.com/en/1.7/topics/auth/default/#django.contrib.auth.decorators.update_session_auth_hash

Sólo quería compartir todo lo q' pude encontrar, y que quede de
referencia por si le sucede a alguien más.

Saludos!
Horacio




--
Horacio G. de Oro

      Web: http://www.data-tsunami.com
      Cel: (03572) 15525359
      Cel: +54 9 3572 525359
 LinkedIn: https://www.linkedin.com/in/hgdeoro

Servidores Linux · Desarrollo de aplicaciones web Python y Java ·
DevOps · Big Data


More information about the pyar mailing list