SECURITY (critical): If username provided, any Yubikey could be used to log in.
authorDan
Thu, 30 Apr 2009 16:11:40 -0400
changeset 17 e04c0f64e972
parent 16 3163b9f58ae8
child 18 dd8c53454f31
SECURITY (critical): If username provided, any Yubikey could be used to log in.
plugins/yubikey/auth.php
plugins/yubikey/yubikey.js
--- a/plugins/yubikey/auth.php	Thu Apr 30 16:11:13 2009 -0400
+++ b/plugins/yubikey/auth.php	Thu Apr 30 16:11:40 2009 -0400
@@ -75,7 +75,20 @@
     }
     else
     {
-      // user did enter an OTP
+      // 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 . '\';');
+      if ( !$q )
+        $db->die_json();
+      if ( $db->numrows() < 1 )
+      {
+        $db->free_result();
+        return array(
+            'mode' => 'error',
+            'error' => 'yubiauth_err_key_not_authorized'
+          );
+      }
+      $db->free_result();
       $do_validate_otp = true;
     }
   }
@@ -134,6 +147,15 @@
         $session->sql('INSERT INTO ' . table_prefix . "logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES\n"
                    . '  (\'security\', \'' . $auth_log_prefix . 'auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \'(Yubikey)\', '
                       . '\''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')');
+      
+      if ( $otp_check['error'] === 'http_failed' )
+      {
+        return array(
+            'mode' => 'error',
+            'error' => 'yubiauth_err_' . $otp_check['error'],
+            'http_error' => $otp_check['http_error']
+          );
+      }
       return array(
           'mode' => 'error',
           'error' => 'yubiauth_err_' . $otp_check['error']
--- a/plugins/yubikey/yubikey.js	Thu Apr 30 16:11:13 2009 -0400
+++ b/plugins/yubikey/yubikey.js	Thu Apr 30 16:11:40 2009 -0400
@@ -145,68 +145,49 @@
   $(ta.parentNode).remove('p');
   yubikey_otp_current = ta.value;
   
-  $('h3', ta.parentNode).text($lang.get('yubiauth_msg_validating_otp'));
+  miniPromptDestroy(ta, true);
   
-  ajaxPost(makeUrlNS('Special', 'Yubikey'), 'get_flags=' + ta.value.substr(0, 12), function(ajax)
+  if ( logindata )
+  {
+    if ( logindata.mb_object )
     {
-      if ( ajax.readyState == 4 && ajax.status == 200 )
+      // login window is open
+      if ( user_level == USER_LEVEL_GUEST )
+      {
+        var show_username = response.flags & YK_SEC_NORMAL_USERNAME;
+        var show_password = response.flags & YK_SEC_NORMAL_PASSWORD;
+      }
+      else
       {
-        miniPromptDestroy(ta);
-        if ( !check_json_response(ajax.responseText) )
-        {
-          handle_invalid_json(ajax.responseText);
-          return false;
-        }
-        $('h3', ta.parentNode).text($lang.get('yubiauth_msg_otp_valid'));
-        var response = parseJSON(ajax.responseText);
-        if ( response.mode == 'error' )
-        {
-          alert('Yubikey server-side processing error: \n' + response.error);
-          return false;
-        }
-        if ( logindata )
+        var show_username = response.flags & YK_SEC_ELEV_USERNAME;
+        var show_password = response.flags & YK_SEC_ELEV_PASSWORD;
+      }
+      if ( !show_username )
+        $('#ajax_login_field_username').parent('td').hide().prev().hide();
+      if ( !show_password )
+        $('#ajax_login_field_password').parent('td').hide().prev().hide();
+      
+      var can_submit = true;
+      if ( show_username && !$('#ajax_login_field_username').attr('value') )
+      {
+        $('#ajax_login_field_password').focus();
+        can_submit = false;
+      }
+      if ( show_password && !$('#ajax_login_field_password').attr('value') )
+      {
+        if ( can_submit )
         {
-          if ( logindata.mb_object )
-          {
-            // login window is open
-            if ( user_level == USER_LEVEL_GUEST )
-            {
-              var show_username = response.flags & YK_SEC_NORMAL_USERNAME;
-              var show_password = response.flags & YK_SEC_NORMAL_PASSWORD;
-            }
-            else
-            {
-              var show_username = response.flags & YK_SEC_ELEV_USERNAME;
-              var show_password = response.flags & YK_SEC_ELEV_PASSWORD;
-            }
-            if ( !show_username )
-              $('#ajax_login_field_username').parent('td').hide().prev().hide();
-            if ( !show_password )
-              $('#ajax_login_field_password').parent('td').hide().prev().hide();
-            
-            var can_submit = true;
-            if ( show_username && !$('#ajax_login_field_username').attr('value') )
-            {
-              $('#ajax_login_field_password').focus();
-              can_submit = false;
-            }
-            if ( show_password && !$('#ajax_login_field_password').attr('value') )
-            {
-              if ( can_submit )
-              {
-                $('#ajax_login_field_password').focus();
-              }
-              can_submit = false;
-            }
-            
-            if ( can_submit )
-            {
-              $('#messageBoxButtons input:button:first').click();
-            }
-          }
+          $('#ajax_login_field_password').focus();
         }
+        can_submit = false;
       }
-    });
+      
+      if ( can_submit )
+      {
+        $('#messageBoxButtons input:button:first').click();
+      }
+    }
+  }
 }
 
 function yk_clear(field_id, status_id)