valid_password를 고안하는 데 이상한 문제가 있습니까?


78

지난 2 시간 동안 나는 로그인을 허용하지 않는 이상한 문제를 devise에서 디버깅하려고했습니다.

내가 언급하는 내용은 다음과 같습니다.

password 
=> 'vinodsobale'

password == 'vinodsobale'
=> true

resource.valid_password?(password)

=> false

resource.valid_password?('vinodsobale')

=> true

스크린 샷도 첨부 :

여기에 이미지 설명 입력 참고 : devise 내부에서 디버거를 활성화 했으므로 위의 코드는 내부 코드를 고안했습니다.

나에게 그것은 Devise.secure_compare.


2
GitHub 문제를여시겠습니까? 재현 가능한 테스트를 사용하는 것이 좋습니다.
vemv

4
@Viren-루비 나 고안에 대한 단서가 없지만 주어진 암호의 인코딩을 확인합니다.
MByD

3
당신은 password.encoding우리에게 결과를 말할 수 있습니까 ? 이것이 내가 거기에서 잘못 될 것이라고 생각할 수있는 유일한 것입니다. 또한 ::BCrypt::Engine.hash_secret(password, salt)실제로 저장된 해시를 가지고 놀 거나 비교할 수 있습니다 . 그 비교를 위해 text.bytes또한 유용 할 수 있습니다.
Rudolf

4
확인 password.bytes하고 확인 'vinodsobale'.bytes하기 위해 할 수 있습니까 ?
루돌프

3
@ lad2025, "저장된 사람"이란 무엇을 의미합니까? 그것은 password? 그렇다면 NULL character \0유니 코드로 인코딩해야하며을 password == 'vinodsobale'반환해서는 안됩니다 true.
vutran 2015

답변:


3

이 문제는 수정 된 Ruby 2.2.0의 알려진 문자열 손상 버그로 인해 발생합니다. 2.2.2 .

버그 보고서에 설명 된대로 BCrypt가 C 확장에서 특정 문자열 생성 API를 호출 할 때 손상이 발생했습니다.이 API는 Devise v3.3.0 ::BCrypt::Engine.hash_secretDevise::Models::DatabaseAuthenticatable#valid_password?메서드 에서 호출 하여 트리거되었습니다 . Devise 별 해결 방법이 버그에 대한 이 v3.5.0에 게시되었습니다.

해결책은 다음 중 하나입니다.

  • Ruby를로 다운 그레이드 < 2.2.0하거나로 업그레이드하십시오 >= 2.2.2.
  • Devise를 >= 3.5.0.

0

어때

resource.valid_password?(password.to_s)

도움이되기를 바랍니다.


3
게시물을 편집하고 이것이 작동하는 이유를 설명하십시오.
Rohit Gupta 2015

왜 이것이 효과가 있다고 생각합니까? 나는 이것에 대한 많은 문제를 먼저 보았습니다. 나는 이미 password == 'vinodsobale' 일치를 언급했습니다 . 그것은 (우리 모두가 볼 수있는) vinodsoble유형의 경우 에도 마찬가지 입니다. 두 번째로 방금 언급 한 코드는 devise 코드를 열고 몽키 패치하는 것과 같이 구현하려는 내부 코드의 일부입니다. stringpasswordstring.to_s
Viren

1
오른쪽에 유효하지 않은 유형이 있으면 equal 연산자가 자동으로 to_s 메소드를 호출 할 수 있습니다. 그러나 나는 단지 추측하고있다. 해봤 어?
Pablo Jomer 2015

그럴듯한 설명입니다.
sevenseacat

2
당신이 사용 password == 'vinosobale'. password === 'vidodsobale' 성냥 을 시도해 볼 수 있습니까? 이 질문을 읽을 수 있습니까 -stackoverflow.com/questions/7156955/… ?
Сергій Назаревич

0

Devise DatabaseAuthenticatable#valid_password?Encryptor::compare2 개의 객체, 현재 저장된 비밀번호와 비교하려는 새 비밀번호를 취하는 메소드를 사용하고 있습니다.이 메소드에는 중간에있는 두 번째 매개 변수를 수정하여 대신 객체를 수정하는 부작용이 있다고 생각합니다. 한 번은 두 번 수정되어 잘못된 결과가 발생하므로 중복 된 암호 개체를 전달하면 작동 할 수 있습니다. 사용해 볼 수있어?valid_password? password.dup


이 경우 resource.valid_password?('vinodsobale')내가 이것을 실행할 때마다 문자열을 제공 할 때마다 수정이 일어나지 않는 이유는 작동하고return true
Viren

0

원본 소스와 본체 간의 인코딩 문제 일 수 있습니다. 를 실행 password.codepoints하면 실제 인코딩을 볼 수 있습니다. 실행 .codepoints원시 '암호'문자열은 반환해야합니다 [112, 97, 115, 115, 119, 111, 114, 100].

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.