From acdf792dafea095612a860ac93b4ed923c02f255 Mon Sep 17 00:00:00 2001 From: Zankaria Date: Wed, 16 Apr 2025 14:32:14 +0200 Subject: [PATCH 1/4] hide.php: add hide.php to the functions --- inc/functions/hide.php | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 inc/functions/hide.php diff --git a/inc/functions/hide.php b/inc/functions/hide.php new file mode 100644 index 00000000..bf972751 --- /dev/null +++ b/inc/functions/hide.php @@ -0,0 +1,6 @@ + Date: Wed, 16 Apr 2025 14:32:54 +0200 Subject: [PATCH 2/4] composer: add hide.php --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index d0345e3b..21fff51a 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,7 @@ "inc/polyfill.php", "inc/error.php", "inc/functions.php", + "inc/functions/hide.php", "inc/functions/net.php" ] }, From 8cffb479fa52a8e83e8817d792d0ca4020d91598 Mon Sep 17 00:00:00 2001 From: Zankaria Date: Wed, 16 Apr 2025 14:38:07 +0200 Subject: [PATCH 3/4] functions.php: use secure_hash where appropriate --- inc/functions.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index def00287..a37e2001 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -11,6 +11,7 @@ if (realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) { $microtime_start = microtime(true); +use Vichan\Functions\Hide; use Lifo\IP\IP; // for expanding IPv6 address in DNSBL() // the user is not currently logged in as a moderator @@ -1691,7 +1692,7 @@ function checkSpam(array $extra_salt = array()) { $_hash = sha1($_hash . $extra_salt); if ($hash != $_hash) { - return true; + return true; } $query = prepare('SELECT `passed` FROM ``antispam`` WHERE `hash` = :hash'); @@ -2583,11 +2584,11 @@ function rrmdir($dir) { function poster_id($ip, $thread) { global $config; - if ($id = event('poster-id', $ip, $thread)) + if ($id = event('poster-id', $ip, $thread)) { return $id; + } - // Confusing, hard to brute-force, but simple algorithm - return substr(sha1(sha1($ip . $config['secure_trip_salt'] . $thread) . $config['secure_trip_salt']), 0, $config['poster_id_length']); + return \substr(Hide\secure_hash($ip . $config['secure_trip_salt'] . $thread . $config['secure_trip_salt'], false), 0, $config['poster_id_length']); } function generate_tripcode($name) { @@ -2615,7 +2616,7 @@ function generate_tripcode($name) { if (isset($config['custom_tripcode']["##{$trip}"])) $trip = $config['custom_tripcode']["##{$trip}"]; else - $trip = '!!' . substr(crypt($trip, str_replace('+', '.', '_..A.' . substr(base64_encode(sha1($trip . $config['secure_trip_salt'], true)), 0, 4))), -10); + $trip = '!!' . substr(crypt($trip, str_replace('+', '.', '_..A.' . substr(Hide\secure_hash($trip . $config['secure_trip_salt'], false), 0, 4))), -10); } else { if (isset($config['custom_tripcode']["#{$trip}"])) $trip = $config['custom_tripcode']["#{$trip}"]; From 3c0779992a764f07f36b54f2bf12a1bb32e6e3a1 Mon Sep 17 00:00:00 2001 From: Zankaria Date: Wed, 16 Apr 2025 14:26:41 +0200 Subject: [PATCH 4/4] auth.php: use secure salt source, use a cryptographically secure hashing algorithm for login tokens --- inc/mod/auth.php | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/inc/mod/auth.php b/inc/mod/auth.php index 01b234a1..326f6f53 100644 --- a/inc/mod/auth.php +++ b/inc/mod/auth.php @@ -5,7 +5,7 @@ */ use Vichan\Context; -use Vichan\Functions\Net; +use Vichan\Functions\{Hide, Net}; defined('TINYBOARD') or exit; @@ -14,30 +14,32 @@ function mkhash($username, $password, $salt = false) { global $config; if (!$salt) { - // create some sort of salt for the hash - $salt = substr(base64_encode(sha1(rand() . time(), true) . $config['cookies']['salt']), 0, 15); - + // Create some salt for the hash. + $salt = \bin2hex(\random_bytes(15)); // 20 characters. $generated_salt = true; + } else { + $generated_salt = false; } // generate hash (method is not important as long as it's strong) - $hash = substr( - base64_encode( - md5( - $username . $config['cookies']['salt'] . sha1( - $username . $password . $salt . ( - $config['mod']['lock_ip'] ? $_SERVER['REMOTE_ADDR'] : '' - ), true - ) . sha1($config['password_crypt_version']) // Log out users being logged in with older password encryption schema - , true - ) - ), 0, 20 + $hash = \substr( + Hide\secure_hash( + $username . $config['cookies']['salt'] . Hide\secure_hash( + $username . $password . $salt . ( + $config['mod']['lock_ip'] ? $_SERVER['REMOTE_ADDR'] : '' + ), true + ) . Hide\secure_hash($config['password_crypt_version'], true), // Log out users being logged in with older password encryption schema + false + ), + 0, + 40 ); - if (isset($generated_salt)) - return array($hash, $salt); - else + if ($generated_salt) { + return [ $hash, $salt ]; + } else { return $hash; + } } function crypt_password($password) { @@ -50,16 +52,13 @@ function crypt_password($password) { } function test_password($password, $salt, $test) { - global $config; - // Version = 0 denotes an old password hashing schema. In the same column, the // password hash was kept previously $version = (strlen($salt) <= 8) ? (int) $salt : 0; if ($version == 0) { $comp = hash('sha256', $salt . sha1($test)); - } - else { + } else { $comp = crypt($test, $password); } return array($version, hash_equals($password, $comp));