SECURITY: Fixed ability to log into an account with someone else's Yubikey...
authorDan Fuhry <dan@enanocms.org>
Fri, 11 Nov 2011 00:33:28 -0500
changeset 38 d109af008343
parent 37 5e946a3f405b
child 39 6212d849ab08
SECURITY: Fixed ability to log into an account with someone else's Yubikey...
plugins/Yubikey.php
plugins/yubikey/auth.php
--- 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.