Attempt to speed up signin but still largely avoid timing attacks, a=chris
Attempt to speed up signin but still largely avoid timing attacks, a=chris
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