From c7bb61f2ff39de7af9d9915f255610fcf55f143c Mon Sep 17 00:00:00 2001 From: fowr <89118232+perdedora@users.noreply.github.com> Date: Thu, 20 Jun 2024 10:32:12 -0300 Subject: [PATCH 1/4] posts.sql: update column password --- templates/posts.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/posts.sql b/templates/posts.sql index 9c468c97..71bad994 100755 --- a/templates/posts.sql +++ b/templates/posts.sql @@ -13,7 +13,7 @@ CREATE TABLE IF NOT EXISTS ``posts_{{ board }}`` ( `files` text DEFAULT NULL, `num_files` int(11) DEFAULT 0, `filehash` text CHARACTER SET ascii, - `password` varchar(20) DEFAULT NULL, + `password` varchar(64) DEFAULT NULL, `ip` varchar(39) CHARACTER SET ascii NOT NULL, `sticky` int(1) NOT NULL, `locked` int(1) NOT NULL, From 8b2f0025823edf6c2e03499fef091c4df04da310 Mon Sep 17 00:00:00 2001 From: fowr <89118232+perdedora@users.noreply.github.com> Date: Thu, 20 Jun 2024 10:11:47 -0300 Subject: [PATCH 2/4] hash poster passwords --- inc/config.php | 3 +++ inc/functions.php | 5 +++++ install.php | 1 + post.php | 9 ++++----- templates/installer/config.html | 3 +++ tools/hash-passwords.php | 17 +++++++++++++++++ 6 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 tools/hash-passwords.php diff --git a/inc/config.php b/inc/config.php index 633cdd33..08b01ead 100644 --- a/inc/config.php +++ b/inc/config.php @@ -200,6 +200,9 @@ // Used to salt secure tripcodes ("##trip") and poster IDs (if enabled). $config['secure_trip_salt'] = ')(*&^%$#@!98765432190zyxwvutsrqponmlkjihgfedcba'; + // Used to salt poster passwords. + $config['secure_password_salt'] = 'wKJSb7M5SyzMcFWD2gPO3j2RYUSO9B789!@#$%^&*()'; + /* * ==================== * Flood/spam settings diff --git a/inc/functions.php b/inc/functions.php index 767dfc06..66cd6fa7 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -3082,3 +3082,8 @@ function strategy_first($fun, $array) { return array('defer'); } } + +function hashPassword($password) { + global $config; + return hash('sha3-256', $password . $config['secure_password_salt']); +} diff --git a/install.php b/install.php index bc3ba7d4..7663a503 100644 --- a/install.php +++ b/install.php @@ -881,6 +881,7 @@ if ($step == 0) { $config['cookies']['salt'] = substr(base64_encode(sha1(rand())), 0, 30); $config['secure_trip_salt'] = substr(base64_encode(sha1(rand())), 0, 30); + $config['secure_password_salt'] = substr(base64_encode(sha1(rand())), 0, 30); echo Element('page.html', array( 'body' => Element('installer/config.html', array( diff --git a/post.php b/post.php index 642e8057..fa069370 100644 --- a/post.php +++ b/post.php @@ -530,10 +530,12 @@ function handle_delete(Context $ctx) $password = &$_POST['password']; - if ($password == '') { + if (empty($password)) { error($config['error']['invalidpassword']); } + $password = hashPassword($_POST['password']); + $delete = []; foreach ($_POST as $post => $value) { if (preg_match('/^delete_(\d+)$/', $post, $m)) { @@ -1013,7 +1015,7 @@ function handle_post(Context $ctx) $post['subject'] = $_POST['subject']; $post['email'] = str_replace(' ', '%20', htmlspecialchars($_POST['email'])); $post['body'] = $_POST['body']; - $post['password'] = $_POST['password']; + $post['password'] = hashPassword($_POST['password']); $post['has_file'] = (!isset($post['embed']) && (($post['op'] && !isset($post['no_longer_require_an_image_for_op']) && $config['force_image_op']) || count($_FILES) > 0)); if (!$dropped_post) { @@ -1204,9 +1206,6 @@ function handle_post(Context $ctx) error($config['error']['toolong_body']); } } - if (mb_strlen($post['password']) > 20) { - error(sprintf($config['error']['toolong'], 'password')); - } } wordfilters($post['body']); diff --git a/templates/installer/config.html b/templates/installer/config.html index 973328f5..00a5b241 100644 --- a/templates/installer/config.html +++ b/templates/installer/config.html @@ -88,6 +88,9 @@ + + + diff --git a/tools/hash-passwords.php b/tools/hash-passwords.php new file mode 100644 index 00000000..3c6463ee --- /dev/null +++ b/tools/hash-passwords.php @@ -0,0 +1,17 @@ +execute() or error(db_error($query)); + + while($entry = $query->fetch(PDO::FETCH_ASSOC)) { + $update_query = prepare(sprintf("UPDATE ``posts_%s`` SET `password` = :password WHERE `password` = :password_org", $_board['uri'])); + $update_query->bindValue(':password', hashPassword($entry['password'])); + $update_query->bindValue(':password_org', $entry['password']); + $update_query->execute() or error(db_error()); + } + } From 57324f169de49ba3a870dd9d8e33466c5d4c6442 Mon Sep 17 00:00:00 2001 From: Zankaria Date: Fri, 27 Dec 2024 15:29:02 +0100 Subject: [PATCH 3/4] post.php: restore password length limit --- post.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/post.php b/post.php index fa069370..0a7959c2 100644 --- a/post.php +++ b/post.php @@ -1011,6 +1011,11 @@ function handle_post(Context $ctx) } } + // We must do this check now before the passowrd is hashed and overwritten. + if (\mb_strlen($_POST['password']) > 20) { + error(\sprintf($config['error']['toolong'], 'password')); + } + $post['name'] = $_POST['name'] != '' ? $_POST['name'] : $config['anonymous']; $post['subject'] = $_POST['subject']; $post['email'] = str_replace(' ', '%20', htmlspecialchars($_POST['email'])); From de75d12bc5242654ae8410e8e15765bdd4356c95 Mon Sep 17 00:00:00 2001 From: Zankaria Date: Fri, 27 Dec 2024 15:35:02 +0100 Subject: [PATCH 4/4] hash-passwords.php: minor refactor --- tools/hash-passwords.php | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/tools/hash-passwords.php b/tools/hash-passwords.php index 3c6463ee..0002bd70 100644 --- a/tools/hash-passwords.php +++ b/tools/hash-passwords.php @@ -2,16 +2,15 @@ require_once dirname(__FILE__) . '/inc/cli.php'; -$boards = listBoards(); - foreach ($boards as &$_board) { - query(sprintf('ALTER TABLE ``posts_%s`` MODIFY `password` varchar(64) DEFAULT NULL;', $_board['uri'])) or error(db_error()); - $query = prepare(sprintf("SELECT DISTINCT `password` FROM ``posts_%s``", $_board['uri'])); - $query->execute() or error(db_error($query)); +foreach (listBoards(true) as $uri) { + query(\sprintf('ALTER TABLE ``posts_%s`` MODIFY `password` varchar(64) DEFAULT NULL;', $uri)) or error(db_error()); + $query = prepare(\sprintf("SELECT DISTINCT `password` FROM ``posts_%s``", $uri)); + $query->execute() or error(db_error($query)); - while($entry = $query->fetch(PDO::FETCH_ASSOC)) { - $update_query = prepare(sprintf("UPDATE ``posts_%s`` SET `password` = :password WHERE `password` = :password_org", $_board['uri'])); - $update_query->bindValue(':password', hashPassword($entry['password'])); - $update_query->bindValue(':password_org', $entry['password']); - $update_query->execute() or error(db_error()); - } - } + while($entry = $query->fetch(\PDO::FETCH_ASSOC)) { + $update_query = prepare(\sprintf("UPDATE ``posts_%s`` SET `password` = :password WHERE `password` = :password_org", $uri)); + $update_query->bindValue(':password', hashPassword($entry['password'])); + $update_query->bindValue(':password_org', $entry['password']); + $update_query->execute() or error(db_error()); + } +}