From c91c58ed078aa5db915442c36f7580a5fb02dd3c Mon Sep 17 00:00:00 2001 From: Zankaria Date: Wed, 3 Apr 2024 19:16:56 +0200 Subject: [PATCH 1/4] Fix: substitute deprecated string interning syntax --- inc/functions.php | 6 +++--- inc/mod/pages.php | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index 50e0ca38..2f23ef09 100755 --- a/inc/functions.php +++ b/inc/functions.php @@ -1614,7 +1614,7 @@ function checkMute() { if ($config['cache']['enabled']) { // Cached mute? - if (($mute = cache::get("mute_${_SERVER['REMOTE_ADDR']}")) && ($mutetime = cache::get("mutetime_${_SERVER['REMOTE_ADDR']}"))) { + if (($mute = cache::get("mute_{$_SERVER['REMOTE_ADDR']}")) && ($mutetime = cache::get("mutetime_{$_SERVER['REMOTE_ADDR']}"))) { error(sprintf($config['error']['youaremuted'], $mute['time'] + $mutetime - time())); } } @@ -1633,8 +1633,8 @@ function checkMute() { if ($mute['time'] + $mutetime > time()) { if ($config['cache']['enabled']) { - cache::set("mute_${_SERVER['REMOTE_ADDR']}", $mute, $mute['time'] + $mutetime - time()); - cache::set("mutetime_${_SERVER['REMOTE_ADDR']}", $mutetime, $mute['time'] + $mutetime - time()); + cache::set("mute_{$_SERVER['REMOTE_ADDR']}", $mute, $mute['time'] + $mutetime - time()); + cache::set("mutetime_{$_SERVER['REMOTE_ADDR']}", $mutetime, $mute['time'] + $mutetime - time()); } // Not expired yet error(sprintf($config['error']['youaremuted'], $mute['time'] + $mutetime - time())); diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 1e803424..8a651f51 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -1280,7 +1280,7 @@ function mod_move_reply($originBoard, $postID) { // trigger themes rebuildThemes('post', $targetBoard); // mod log - modLog("Moved post #${postID} to " . sprintf($config['board_abbreviation'], $targetBoard) . " (#${newID})", $originBoard); + modLog("Moved post #{$postID} to " . sprintf($config['board_abbreviation'], $targetBoard) . " (#{$newID})", $originBoard); // return to original board openBoard($originBoard); @@ -1457,7 +1457,7 @@ function mod_move($originBoard, $postID) { } } - modLog("Moved thread #${postID} to " . sprintf($config['board_abbreviation'], $targetBoard) . " (#${newID})", $originBoard); + modLog("Moved thread #{$postID} to " . sprintf($config['board_abbreviation'], $targetBoard) . " (#{$newID})", $originBoard); // build new thread buildThread($newID); From 0dd064b2ea5b35122ca5ac94c5c198679e7008e9 Mon Sep 17 00:00:00 2001 From: papereth <69432409+papereth@users.noreply.github.com> Date: Sat, 4 May 2024 15:01:17 +0100 Subject: [PATCH 2/4] Fix Exif leak in JPEG orientation conversion code https://github.com/vichan-devel/vichan/issues/735 --- post.php | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/post.php b/post.php index 2cc99071..0a0dd94a 100644 --- a/post.php +++ b/post.php @@ -1048,23 +1048,19 @@ if (isset($_POST['delete'])) { error($config['error']['maxsize']); } - - if ($config['convert_auto_orient'] && ($file['extension'] == 'jpg' || $file['extension'] == 'jpeg')) { - // The following code corrects the image orientation. - // Currently only works with the 'convert' option selected but it could easily be expanded to work with the rest if you can be bothered. - if (!($config['redraw_image'] || (($config['strip_exif'] && !$config['use_exiftool']) && ($file['extension'] == 'jpg' || $file['extension'] == 'jpeg')))) { + // The following code corrects the image orientation. + if ($config['convert_auto_orient'] && ($size[2] == IMAGETYPE_JPEG)) { + // 'redraw_image' should already fix image orientation by itself + if (!($config['redraw_image'])) { if (in_array($config['thumb_method'], array('convert', 'convert+gifsicle', 'gm', 'gm+gifsicle'))) { $exif = @exif_read_data($file['tmp_name']); $gm = in_array($config['thumb_method'], array('gm', 'gm+gifsicle')); if (isset($exif['Orientation']) && $exif['Orientation'] != 1) { $error = shell_exec_error(($gm ? 'gm ' : '') . 'convert ' . - escapeshellarg($file['tmp_name']) . ' -auto-orient ' . escapeshellarg($upload)); - + escapeshellarg($file['tmp_name']) . ' -auto-orient ' . escapeshellarg($file['tmp_name'])); if ($error) error(_('Could not auto-orient image!'), null, $error); $size = @getimagesize($file['tmp_name']); - if ($config['strip_exif']) - $file['exif_stripped'] = true; } } } From fff9b88c6d15261eaa83f7bc44bcefc6ed9197e6 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 3/4] hash poster passwords --- inc/config.php | 3 +++ inc/functions.php | 6 ++++++ install.php | 1 + post.php | 16 ++++++++-------- templates/installer/config.html | 3 +++ tools/hash-passwords.php | 17 +++++++++++++++++ 6 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 tools/hash-passwords.php diff --git a/inc/config.php b/inc/config.php index 0cece593..664d1710 100644 --- a/inc/config.php +++ b/inc/config.php @@ -184,6 +184,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 2f23ef09..adf83e9b 100755 --- a/inc/functions.php +++ b/inc/functions.php @@ -3089,3 +3089,9 @@ function check_thread_limit($post) { return $r['count'] >= $config['max_threads_per_hour']; } } + +function hashPassword($password) { + global $config; + + return hash('sha3-256', $password . $config['secure_password_salt']); +} \ No newline at end of file diff --git a/install.php b/install.php index c174771b..0b25ae02 100644 --- a/install.php +++ b/install.php @@ -919,6 +919,7 @@ if ($step == 0) { $sg = new SaltGen(); $config['cookies']['salt'] = $sg->generate(); $config['secure_trip_salt'] = $sg->generate(); + $config['secure_password_salt'] = $sg->generate(); echo Element('page.html', array( 'body' => Element('installer/config.html', array( diff --git a/post.php b/post.php index 0a0dd94a..b7fd5f71 100644 --- a/post.php +++ b/post.php @@ -364,10 +364,11 @@ if (isset($_POST['delete'])) { if (!isset($_POST['board'], $_POST['password'])) error($config['error']['bot']); - $password = &$_POST['password']; - - if ($password == '') + if (empty($_POST['password'])){ error($config['error']['invalidpassword']); + } + + $password = hashPassword($_POST['password']); $delete = array(); foreach ($_POST as $post => $value) { @@ -415,10 +416,11 @@ if (isset($_POST['delete'])) { error(sprintf($config['error']['delete_too_late'], until($post['time'] + $config['max_delete_time']))); } - if ($password != '' && $post['password'] != $password && (!$thread || $thread['password'] != $password)) + if (!hash_equals($post['password'], $password) && (!$thread || !hash_equals($thread['password'], $password))) { error($config['error']['invalidpassword']); + } - if ($post['time'] > time() - $config['delete_time'] && (!$thread || $thread['password'] != $password)) { + if ($post['time'] > time() - $config['delete_time'] && (!$thread || !hash_equals($thread['password'], $password))) { error(sprintf($config['error']['delete_too_soon'], until($post['time'] + $config['delete_time']))); } @@ -767,7 +769,7 @@ if (isset($_POST['delete'])) { $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) { @@ -920,8 +922,6 @@ if (isset($_POST['delete'])) { error($config['error']['toolong_body']); if (!$mod && substr_count($post['body'], "\n") >= $config['maximum_lines']) error($config['error']['toomanylines']); - 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 e9f1d59209cf308442e4a1dc4969ad8db8e9e69c 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 4/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 100644 --- 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,