From d31cf9d1566d6b671933716cb73cd6c5cc9ab802 Mon Sep 17 00:00:00 2001 From: 4n4nk3 <4n4nk3@users.noreply.github> Date: Mon, 16 Jan 2023 11:25:48 +0100 Subject: [PATCH 1/2] Fix insecure persistent login token Signed-off-by: 4n4nk3 <47717886+4n4nk3@users.noreply.github.com> --- logout.php | 8 +- scripts/pi-hole/php/password.php | 14 ++-- scripts/pi-hole/php/persistentlogin_token.php | 83 +++++++++++++++++++ 3 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 scripts/pi-hole/php/persistentlogin_token.php diff --git a/logout.php b/logout.php index baac04c12..cfeaf168d 100644 --- a/logout.php +++ b/logout.php @@ -1,9 +1,15 @@ 0) { // Check for and authorize from persistent cookie if (isset($_COOKIE['persistentlogin'])) { - if (hash_equals($pwhash, $_COOKIE['persistentlogin'])) { + if (checkValidityPersistentLoginToken($_COOKIE['persistentlogin'])) { $_SESSION['auth'] = true; - // Refresh cookie with new expiry - // setcookie( $name, $value, $expire, $path, $domain, $secure, $httponly ) - setcookie('persistentlogin', $pwhash, time() + 60 * 60 * 24 * 7, null, null, null, true); } else { // Invalid cookie $_SESSION['auth'] = false; @@ -61,8 +59,12 @@ function verifyPassword($pwhash, $use_api = false) // Set persistent cookie if selected if (isset($_POST['persistentlogin'])) { - // setcookie( $name, $value, $expire, $path, $domain, $secure, $httponly ) - setcookie('persistentlogin', $pwhash, time() + 60 * 60 * 24 * 7, null, null, null, true); + // Generate cookie with new expiry + $token = genPersistentLoginToken(); + $time = time() + 60 * 60 * 24 * 7; // 7 days + writePersistentLoginToken($token, $time); + // setcookie($name, $value, $expire, $path, $domain, $secure, $httponly) + setcookie('persistentlogin', $token, $time, null, null, null, true); } $_SESSION['auth'] = true; diff --git a/scripts/pi-hole/php/persistentlogin_token.php b/scripts/pi-hole/php/persistentlogin_token.php new file mode 100644 index 000000000..71d75d8ef --- /dev/null +++ b/scripts/pi-hole/php/persistentlogin_token.php @@ -0,0 +1,83 @@ += time()) { + return true; + } + } + } + return false; +} + +function writePersistentLoginToken($token, $time) +{ + $token_file = getPathPersistentLoginToken($token); + + if ($token_file and !file_exists($token_file)) { + $t_file = fopen($token_file, "w"); + if ($t_file) { + // make sure persistent login token file is not readable by other users + chmod($token_file, 0600); + + fwrite($t_file, $time); + fclose($t_file); + return true; + } + } + return false; +} + +function logoutPersistentLoginToken($token) +{ + setcookie('persistentlogin', '', 1); + + $token_file = getPathPersistentLoginToken($token); + if ($token_file and file_exists($token_file) and is_writable($token_file)) { + unlink($token_file); + } +} From 8025a38aca3edc9aa68f5a19b9b77e0675b0c3be Mon Sep 17 00:00:00 2001 From: Adam Warner Date: Wed, 25 Jan 2023 19:00:20 +0000 Subject: [PATCH 2/2] Fix `PHP-CS-Fixer` complaints --- scripts/pi-hole/php/persistentlogin_token.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/scripts/pi-hole/php/persistentlogin_token.php b/scripts/pi-hole/php/persistentlogin_token.php index 71d75d8ef..7338c6efb 100644 --- a/scripts/pi-hole/php/persistentlogin_token.php +++ b/scripts/pi-hole/php/persistentlogin_token.php @@ -7,7 +7,6 @@ * Please see LICENSE file for your rights under this license. */ - function genPersistentLoginToken() { return bin2hex(openssl_random_pseudo_bytes(16)); @@ -19,7 +18,8 @@ function checkSafetyPersistentLoginToken($token) if (ctype_alnum($token) and strlen($token) == 32) { return true; } - error_log("Security alert: presented \"persistentlogin\" token did not pass safety check!", 0); + error_log('Security alert: presented "persistentlogin" token did not pass safety check!', 0); + return false; } @@ -29,9 +29,11 @@ function getPathPersistentLoginToken($token) $session_path = session_save_path(); if ($session_path and checkSafetyPersistentLoginToken($token)) { - $token_file = $session_path . '/ph_plt_' . $token . '.txt'; + $token_file = $session_path.'/ph_plt_'.$token.'.txt'; + return $token_file; } + return false; } @@ -41,7 +43,7 @@ function checkValidityPersistentLoginToken($token) $token_file = getPathPersistentLoginToken($token); if ($token_file and file_exists($token_file) and is_readable($token_file)) { - $t_file = fopen($token_file, "r"); + $t_file = fopen($token_file, 'r'); if ($t_file) { $time = fread($t_file, filesize($token_file)); fclose($t_file); @@ -51,6 +53,7 @@ function checkValidityPersistentLoginToken($token) } } } + return false; } @@ -59,16 +62,18 @@ function writePersistentLoginToken($token, $time) $token_file = getPathPersistentLoginToken($token); if ($token_file and !file_exists($token_file)) { - $t_file = fopen($token_file, "w"); + $t_file = fopen($token_file, 'w'); if ($t_file) { // make sure persistent login token file is not readable by other users chmod($token_file, 0600); fwrite($t_file, $time); fclose($t_file); + return true; } } + return false; }