Attempt to speed up signin but still largely avoid timing attacks, a=chris

Chris Pollett [2020-06-23 19:Jun:rd]
Attempt to speed up signin but still largely avoid timing attacks, a=chris
Filename
src/controllers/AdminController.php
src/library/IndexShard.php
src/library/Utility.php
src/models/SigninModel.php
diff --git a/src/controllers/AdminController.php b/src/controllers/AdminController.php
index e2cd391b1..45c348f8c 100755
--- a/src/controllers/AdminController.php
+++ b/src/controllers/AdminController.php
@@ -101,7 +101,7 @@ class AdminController extends Controller implements CrawlConstants
             $user = $this->model("signin")->getUserId($_SESSION['USER_NAME'],
                 "string");
             $_SESSION['USER_ID'] = $user;
-        } else{
+        } else {
             $user = L\remoteAddress();
         }
         $data['SCRIPT'] = "";
diff --git a/src/library/IndexShard.php b/src/library/IndexShard.php
index 899834985..6c41e8d29 100644
--- a/src/library/IndexShard.php
+++ b/src/library/IndexShard.php
@@ -1892,7 +1892,9 @@ class IndexShard extends PersistentStructure implements CrawlConstants
             } else {
                 $tmp = unpack("N*", substr($postings_info, 4,
                     8));
-                if (!isset($tmp[2])) {continue; }
+                if (!isset($tmp[2])) {
+                    continue;
+                }
                 list(, $offset, $len) = $tmp;
                 if (($len & (1 << 31))) {
                     $this->num_docs_word[$word_id] = (($len >> 16) & 32767);
diff --git a/src/library/Utility.php b/src/library/Utility.php
index 1d9adcbde..517e46381 100755
--- a/src/library/Utility.php
+++ b/src/library/Utility.php
@@ -322,8 +322,9 @@ function addDocIndexPostings(&$postings, $add_offset)
     $postings_len = strlen($postings);
     while($offset < $postings_len) {
         $post_string = nextPostString($postings, $offset);
-        if ($post_string == "" ||
-            !($tmp = unpack("N*", $post_string))) {continue; }
+        if ($post_string == "" || !($tmp = unpack("N*", $post_string))) {
+            continue;
+        }
         $posting_list = call_user_func_array("array_merge",
             array_map(C\NS_LIB . "unpackListModified9", $tmp));
         if (!is_array($posting_list)) {
diff --git a/src/models/SigninModel.php b/src/models/SigninModel.php
index 8cd8d62ee..59410eed4 100755
--- a/src/models/SigninModel.php
+++ b/src/models/SigninModel.php
@@ -41,7 +41,8 @@ use seekquarry\yioop\library as L;
 class SigninModel extends Model
 {
     /**
-     * Checks that a username password pair is valid
+     * Checks that a username password pair is valid. This function
+     * is slow because the underlying crypt to slow
      *
      * @param string $username the username to check
      * @param string $password the password to check
@@ -52,15 +53,27 @@ class SigninModel extends Model
     {
         $db = $this->db;
         $row = $this->getUserDetails($username);
-        if (!$row) {
-            return false;
+        $start_time = microtime(true);
+        if ($row) {
+            $crypt_password = L\crawlCrypt($password, $row['PASSWORD']);
+            $valid_password = ($crypt_password == $row['PASSWORD']);
+        } else {
+            $crypt_password = L\crawlCrypt($password);
+            $valid_password = false;
+        }
+        // crude avoid timing attacks if possible
+        $micro_delta = L\changeInMicrotime($start_time);
+        $sleep_time = intval(1000000 * (0.25 - $micro_delta));
+        if ($sleep_time < 0) {
+            $sleep_time = intval(1000000 * (0.5 - $micro_delta));
+        }
+        if ($sleep_time < 0) {
+            $sleep_time = intval(1000000 * (1 - $micro_delta));
         }
-        // avoid timeing attacks if possible
-        if (function_exists('hash_equals') ) {
-            return hash_equals(L\crawlCrypt($password, $row['PASSWORD']),
-                $row['PASSWORD']);
+        if ($sleep_time > 0) {
+            usleep($sleep_time);
         }
-        return L\crawlCrypt($password, $row['PASSWORD']) == $row['PASSWORD'];
+        return $valid_password;
     }
     /**
      * Get user details from database
ViewGit