¿Problema extraño con devise valid_password?

78

Durante las últimas 2 horas, he intentado depurar un problema extraño en el dispositivo que no me permite iniciar sesión.

Estas son las cosas a las que también me refiero:

password 
=> 'vinodsobale'

password == 'vinodsobale'
=> true

resource.valid_password?(password)

=> false

resource.valid_password?('vinodsobale')

=> true

Adjuntando la captura de pantalla también:

ingrese la descripción de la imagen aquí Nota: He habilitado el depurador dentro del dispositivo, por lo que el código anterior es el código interno del dispositivo.

Para mí, parece un problema en Devise.secure_compare.

Viren
fuente
2
¿Abrir un problema de GitHub? Preferiblemente con una prueba reproducible.
vemv
4
@Viren: no tengo ni idea de ruby ​​o devise, pero verificaría la codificación de la contraseña dada.
MByD
3
¿Puedes hacer una password.encodingy decirnos el resultado? Esto es lo único que se me ocurre que podría salir mal allí. También puede jugar ::BCrypt::Engine.hash_secret(password, salt)y comparar eso con el hash realmente almacenado. Porque esa comparación text.bytestambién puede resultar útil.
Rudolf
4
¿Puedes comprobar password.bytesy 'vinodsobale'.bytessolo para asegurarte?
Rudolf
3
@ lad2025, ¿qué quieres decir con "salvado"? Es el password? Si es así, NULL character \0debería estar codificado en Unicode y password == 'vinodsobale'no debería regresar true.
vutran

Respuestas:

3

Este problema se debe a un error conocido de corrupción de cadenas en Ruby 2.2.0 que se corrigió en 2.2.2.

Como se describe en el informe de error , la corrupción se produjo cuando BCrypt llamó a una API específica de creación de cadenas desde su extensión C, que Devise v3.3.0 activó al llamar ::BCrypt::Engine.hash_secretdesde el Devise::Models::DatabaseAuthenticatable#valid_password?método. En v3.5.0 se publicó una solución alternativa específica de Devise para este error.

La solución es:

  • Degradar Ruby a < 2.2.0, o actualizar a >= 2.2.2;
  • Actualice Devise a >= 3.5.0.
wjordania
fuente
0

Qué tal si

resource.valid_password?(password.to_s)

Espero que te ayude.

Сергій Назаревич
fuente
3
Edite su publicación y explique por qué esto funcionaría.
Rohit Gupta
¿Por qué crees que esto funcionará? Veo muchos problemas con esto, en primer lugar, ya he mencionado, es decir, password == 'vinodsobale' coincidencias. Eso sí, si vinodsoblees de tipo string(que todos podemos ver), entonces passwordtambién es stringasí y .to_sno producirá nada diferente. En segundo lugar, el código que acaba de mencionar es parte del código interno del dispositivo, cómo desea implementarlo, como abrir el código del dispositivo y parchearlo.
Viren
1
Podría ser que el operador igual llame automáticamente al método to_s si hay un tipo no válido en la mano derecha. Pero solo estoy adivinando. ¿Lo intentaste?
Pablo Jomer
es una explicación plausible.
sevenseacat
2
Usaste password == 'vinosobale'. ¿Podrías probar password === 'vidodsobale' partidos? ¿Podrías leer esta pregunta - stackoverflow.com/questions/7156955/… ?
Сергій Назаревич
0

Devise DatabaseAuthenticatable#valid_password?está utilizando un método llamado Encryptor::comparetoma 2 objetos, la contraseña almacenada actual y la nueva contraseña que desea comparar, creo que hay un efecto secundario para este método que modifica el segundo parámetro en el medio, por lo que modificará el objeto en su lugar de una vez, se modificará dos veces, lo que conduce a un resultado falso, por lo que puede funcionar si pasó un objeto duplicado de contraseña. puedes intentar usarvalid_password? password.dup

Emad Elsaid
fuente
Si ese es un caso, ¿por qué no se produce la modificación cuando se proporciona una cadena resource.valid_password?('vinodsobale')cada vez que solía ejecutar esto, solía funcionar y?return true
Viren
0

Podría ser un problema con la codificación entre la fuente original y su consola. Si ejecuta password.codepoints, debería poder ver la codificación real. La ejecución .codepointsen la cadena de 'contraseña' sin procesar debería regresar [112, 97, 115, 115, 119, 111, 114, 100].

Torrey Payne
fuente