SECURITY: Fixed ability to log into an account with someone else's Yubikey...
--- a/plugins/Yubikey.php Fri Nov 11 00:30:49 2011 -0500
+++ b/plugins/Yubikey.php Fri Nov 11 00:33:28 2011 -0500
@@ -120,6 +120,7 @@
err_http_response_error: 'Your OTP could not be validated because the Yubico authentication server reported an error.',
err_malformed_response: 'Your OTP could not be validated because the Yubico authentication server returned an unexpected response.',
err_timestamp_check_failed: 'Your OTP could not be validated because the timestamp of the response from the Yubico authentication server was out of bounds.',
+ err_uid_mismatch: 'This Yubikey is registered to a different user account than the one you are trying to log into.',
err_response_missing_sig: 'Your OTP could not be validated because the Yubico authentication server did not sign its response.',
err_response_invalid_sig: 'Your OTP could not be validated because the signature of the authentication response was invalid.',
err_response_missing_status: '%this.yubiauth_err_malformed_response%',
--- a/plugins/yubikey/auth.php Fri Nov 11 00:30:49 2011 -0500
+++ b/plugins/yubikey/auth.php Fri Nov 11 00:33:28 2011 -0500
@@ -81,7 +81,7 @@
{
// user did enter an OTP; make sure it's associated with the username
$yubi_uid = $db->escape(substr($userdata['yubikey_otp'], 0, 12));
- $q = $db->sql_query('SELECT 1 FROM ' . table_prefix . 'yubikey WHERE yubi_uid = \'' . $yubi_uid . '\';');
+ $q = $db->sql_query('SELECT user_id FROM ' . table_prefix . 'yubikey WHERE yubi_uid = \'' . $yubi_uid . '\';');
if ( !$q )
$db->die_json();
if ( $db->numrows() < 1 )
@@ -92,6 +92,14 @@
'error' => 'yubiauth_err_key_not_authorized'
);
}
+ list($yubi_pair_uid) = $db->fetchrow_num();
+ if ( $yubi_pair_uid !== $user_id )
+ {
+ return array(
+ 'mode' => 'error',
+ 'error' => 'yubiauth_err_uid_mismatch'
+ );
+ }
$db->free_result();
$do_validate_otp = true;
}
@@ -129,6 +137,19 @@
}
list($user_id, $username, $flags) = $db->fetchrow_num();
+
+ if ( $level > USER_LEVEL_MEMBER )
+ {
+ $session->start();
+ if ( $session->user_logged_in && ($session->user_id !== $user_id) )
+ {
+ return array(
+ 'mode' => 'error',
+ 'error' => 'yubiauth_err_uid_mismatch'
+ );
+ }
+ }
+
$do_validate_otp = true;
$do_validate_user = $flags & $user_flag;
$do_validate_pass = $flags & $pass_flag;
@@ -143,6 +164,7 @@
'error' => 'yubiauth_err_nothing_provided'
);
}
+
if ( $do_validate_otp )
{
// We need to validate the OTP.