diff -u password_reset/password_reset.module password_reset_mod/password_reset.module --- password_reset/password_reset.module 2009-02-28 07:34:26.000000000 +0000 +++ password_reset_mod/password_reset.module 2009-10-06 14:13:51.000000000 +0000 @@ -90,7 +90,22 @@ switch ($step) { case 2: $uid = password_reset_uid_get($form_state['values']['username']); - if ($question = password_reset_user_question_get($uid)) { + // try to retrieve question + $question = password_reset_user_question_get($uid); + + if ($question === FALSE) { + /** + * question not found, user does not exist or doesn't have a quuestion selected + * we don't want to give any information away, so we select a question using a checksum over the name + * for consistency (if we do a random select, submitting the form twice will tell an attacker it's an invlid username) + */ + $questions = array_values(password_reset_questions_get()); + if (count($questions) > 0) { + $chksum = crc32(strtolower($form_state['values']['username'])); + $question = (object) array('question' => $questions[abs($chksum % count($questions))]); + } + } + if ($question) { $form['username'] = array('#type' => 'value', '#value' => $form_state['values']['username']); $form['question'] = array('#value' => t('Security question: %question', array('%question' => $question->question))); $form['answer'] = array( @@ -139,17 +154,21 @@ */ function password_reset_form_validate($form, &$form_state) { switch ($form_state['values']['step']) { - case 1: - $uid = password_reset_uid_get($form_state['values']['username']); - if (!$uid) { - form_set_error('username', t('Username not found. Please check and try again.')); - } - break; + /** + * We don't want to give away the information that a username is (in)valid + * + * case 1: + * $uid = password_reset_uid_get($form_state['values']['username']); + * if (!$uid) { + * form_set_error('username', t('Username not found. Please check and try again.')); + * } + * break; + */ case 2: $uid = password_reset_uid_get($form_state['values']['username']); $question = password_reset_user_question_get($uid); if (!$question || trim(strtolower($question->answer)) != trim(strtolower($form_state['values']['answer']))) { - form_set_error('answer', t('Answer incorrect. Please check and try again.')); + form_set_error('answer', t('Username or answer incorrect. Please check and try again.')); } break; }