From a09d834d995599756b62016af7026d2408ecf43a Mon Sep 17 00:00:00 2001 From: CauseFX Date: Mon, 11 Apr 2022 09:52:22 -0700 Subject: [PATCH] added sanitizeUserString and sanitizeEmail functions added sanitize to uploaded image names added sanitize to tabs, categories, users and bookmarks removed svg files from approved image lists --- api/classes/organizr.class.php | 72 ++++++++++++++++++++++++++-- api/functions/log-functions.php | 2 +- api/functions/organizr-functions.php | 1 - api/plugins/bookmark/plugin.php | 13 +++++ 4 files changed, 83 insertions(+), 5 deletions(-) diff --git a/api/classes/organizr.class.php b/api/classes/organizr.class.php index 1cf67003d..4b85009f7 100644 --- a/api/classes/organizr.class.php +++ b/api/classes/organizr.class.php @@ -1895,7 +1895,7 @@ public function uploadImage() $tempFile = $_FILES['file']['tmp_name']; $targetPath = $this->root . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'userTabs' . DIRECTORY_SEPARATOR; $this->makeDir($targetPath); - $targetFile = $targetPath . $_FILES['file']['name']; + $targetFile = $targetPath . $this->sanitizeUserString($_FILES['file']['name']); $this->setAPIResponse(null, pathinfo($_FILES['file']['name'], PATHINFO_BASENAME) . ' has been uploaded', null); return move_uploaded_file($tempFile, $targetFile); } @@ -4873,7 +4873,7 @@ public function addTab($array) $array['type'] = ($array['type']) ?? 1; $array['order'] = ($array['order']) ?? $this->getNextTabOrder() + 1; if (array_key_exists('name', $array)) { - $array['name'] = htmlspecialchars($array['name']); + $array['name'] = $this->sanitizeUserString($array['name']); if ($this->isTabNameTaken($array['name'])) { $this->setAPIResponse('error', 'Tab name: ' . $array['name'] . ' is already taken', 409); return false; @@ -4923,7 +4923,7 @@ public function updateTab($id, $array) return false; } if (array_key_exists('name', $array)) { - $array['name'] = htmlspecialchars($array['name']); + $array['name'] = $this->sanitizeUserString($array['name']); if ($this->isTabNameTaken($array['name'], $id)) { $this->setAPIResponse('error', 'Tab name: ' . $array['name'] . ' is already taken', 409); return false; @@ -4995,6 +4995,7 @@ public function addCategory($array) $array['order'] = ($array['order']) ?? $this->getNextCategoryOrder() + 1; $array['category_id'] = ($array['category_id']) ?? $this->getNextCategoryId() + 1; if (array_key_exists('category', $array)) { + $array['category'] = $this->sanitizeUserString($array['category']); if ($this->isCategoryNameTaken($array['category'])) { $this->setAPIResponse('error', 'Category name: ' . $array['category'] . ' is already taken', 409); return false; @@ -5005,6 +5006,9 @@ public function addCategory($array) } if (!array_key_exists('image', $array)) { $this->setAPIResponse('error', 'Category image was not supplied', 422); + return false; + } else { + $array['image'] = $this->sanitizeUserString($array['image']); } $response = [ array( @@ -5039,11 +5043,15 @@ public function updateCategory($id, $array) return false; } if (array_key_exists('category', $array)) { + $array['category'] = $this->sanitizeUserString($array['category']); if ($this->isCategoryNameTaken($array['category'], $id)) { $this->setAPIResponse('error', 'Category name: ' . $array['category'] . ' is already taken', 409); return false; } } + if (array_key_exists('image', $array)) { + $array['image'] = $this->sanitizeUserString($array['image']); + } if (array_key_exists('default', $array)) { if ($array['default']) { $this->clearCategoryDefault(); @@ -6184,6 +6192,21 @@ public function allEmbyUsers($newOnly = false) return false; } + public function validateEmail($email) + { + return filter_var(trim($email), FILTER_VALIDATE_EMAIL); + } + + public function sanitizeEmail($email) + { + return filter_var(trim($email), FILTER_SANITIZE_EMAIL); + } + + public function sanitizeUserString($string) + { + return htmlspecialchars(trim($string)); + } + public function updateUser($id, $array) { if (!$id) { @@ -6211,6 +6234,7 @@ public function updateUser($id, $array) $this->setAPIResponse('error', 'Username was set but empty', 409); return false; } + $array['username'] = $this->sanitizeUserString($array['username']); if ($this->usernameTaken($array['username'], $array['username'], $id)) { $this->setAPIResponse('error', 'Username: ' . $array['username'] . ' is already taken', 409); return false; @@ -6221,6 +6245,12 @@ public function updateUser($id, $array) $this->setAPIResponse('error', 'Email was set but empty', 409); return false; } + if ($this->validateEmail($array['email'])) { + $array['email'] = $this->sanitizeEmail($array['email']); + } else { + $this->setResponse(409, 'Email is not a valid email', ['email' => $array['email']]); + return false; + } if ($this->usernameTaken($array['email'], $array['email'], $id)) { $this->setAPIResponse('error', 'Email: ' . $array['email'] . ' is already taken', 409); return false; @@ -6260,6 +6290,9 @@ public function updateUser($id, $array) } $array['password'] = password_hash($array['password'], PASSWORD_BCRYPT); } + if (array_key_exists('image', $array)) { + $array['image'] = $this->sanitizeUserString($array['image']); + } if (array_key_exists('register_date', $array)) { $this->setAPIResponse('error', 'Cannot update register date', 409); return false; @@ -6317,10 +6350,30 @@ public function addUser($array) $this->setAPIResponse('error', 'Username was not supplied', 409); return false; } + if ($username == '') { + $this->setResponse(409, 'Username was set but empty'); + return false; + } else { + $username = $this->sanitizeUserString($username); + } if (!$password) { $this->setAPIResponse('error', 'Password was not supplied', 409); return false; } + if (!$email) { + $this->setAPIResponse('error', 'Email was set not supplied', 409); + return false; + } + if ($email == '') { + $this->setAPIResponse('error', 'Email was set but empty', 409); + return false; + } + if ($this->validateEmail($email)) { + $email = $this->sanitizeEmail($email); + } else { + $this->setResponse(409, 'Email is not a valid email', ['email' => $email]); + return false; + } $this->setLoggerChannel('User Management'); if ($this->createUser($username, $password, $email)) { $this->logger->info('Account created for [' . $username . ']'); @@ -6340,10 +6393,21 @@ public function createUser($username, $password, $email = null) $this->setAPIResponse('error', 'Username was set but empty', 409); return false; } + $username = $this->sanitizeUserString($username); if (!$password) { $this->setAPIResponse('error', 'Password was set but empty', 409); return false; } + if ($email == '') { + $this->setAPIResponse('error', 'Email was set but empty', 409); + return false; + } + if ($this->validateEmail($email)) { + $email = $this->sanitizeEmail($email); + } else { + $this->setResponse(409, 'Email is not a valid email', ['email' => $email]); + return false; + } if ($this->usernameTaken($username, $email)) { $this->setAPIResponse('error', 'Username: ' . $username . ' or Email: ' . $email . ' is already taken', 409); return false; @@ -6397,6 +6461,7 @@ public function updateGroup($id, $array) $this->setAPIResponse('error', 'Group was set but empty', 409); return false; } + $array['group'] = $this->sanitizeUserString($array['group']); if ($this->isGroupNameTaken($array['group'], $id)) { $this->setAPIResponse('error', 'Group name: ' . $array['group'] . ' is already taken', 409); return false; @@ -6476,6 +6541,7 @@ public function addGroup($array) $array['default'] = ($array['default']) ?? 0; $array['group_id'] = $this->getNextGroupOrder() + 1; if (array_key_exists('group', $array)) { + $array['group'] = $this->sanitizeUserString($array['group']); if ($this->isGroupNameTaken($array['group'])) { $this->setAPIResponse('error', 'Group name: ' . $array['group'] . ' is already taken', 409); return false; diff --git a/api/functions/log-functions.php b/api/functions/log-functions.php index b12974bc0..0ef91e070 100644 --- a/api/functions/log-functions.php +++ b/api/functions/log-functions.php @@ -212,7 +212,7 @@ public function setLoggerChannel($channel = 'Organizr', $username = null) if ($this->hasDB()) { $setLogger = false; if ($username) { - $username = htmlspecialchars($username); + $username = $this->sanitizeUserString($username); } if ($this->logger) { if ($channel) { diff --git a/api/functions/organizr-functions.php b/api/functions/organizr-functions.php index ea8a4745b..7cd248582 100644 --- a/api/functions/organizr-functions.php +++ b/api/functions/organizr-functions.php @@ -216,7 +216,6 @@ public function approvedFileExtension($filename, $type = 'image') case 'png': case 'jpeg': case 'jpg': - case 'svg': return true; default: return false; diff --git a/api/plugins/bookmark/plugin.php b/api/plugins/bookmark/plugin.php index 64b6b78a7..5f176c3b2 100644 --- a/api/plugins/bookmark/plugin.php +++ b/api/plugins/bookmark/plugin.php @@ -570,6 +570,7 @@ public function _addTab($array) $array['enabled'] = ($array['enabled']) ?? 0; $array['order'] = ($array['order']) ?? $this->_getNextBookmarkTabOrder() + 1; if (array_key_exists('name', $array)) { + $array['name'] = $this->sanitizeUserString($array['name']); if ($this->_isBookmarkTabNameTaken($array['name'])) { $this->setAPIResponse('error', 'Tab name: ' . $array['name'] . ' is already taken', 409); return false; @@ -585,8 +586,11 @@ public function _addTab($array) if (!array_key_exists('image', $array)) { $this->setAPIResponse('error', 'Tab image was not supplied', 422); return false; + } else { + $array['image'] = $this->sanitizeUserString($array['image']); } if (array_key_exists('background_color', $array)) { + $array['background_color'] = $this->sanitizeUserString($array['background_color']); if (!$this->_checkColorHexCode($array['background_color'])) { $this->setAPIResponse('error', 'Tab background color is invalid', 422); return false; @@ -596,6 +600,7 @@ public function _addTab($array) return false; } if (array_key_exists('text_color', $array)) { + $array['text_color'] = $this->sanitizeUserString($array['text_color']); if (!$this->_checkColorHexCode($array['text_color'])) { $this->setAPIResponse('error', 'Tab text color is invalid', 422); return false; @@ -636,23 +641,29 @@ public function _updateTab($id, $array) return false; } if (array_key_exists('name', $array)) { + $array['name'] = $this->sanitizeUserString($array['name']); if ($this->_isBookmarkTabNameTaken($array['name'], $id)) { $this->setAPIResponse('error', 'Tab name: ' . $array['name'] . ' is already taken', 409); return false; } } if (array_key_exists('background_color', $array)) { + $array['background_color'] = $this->sanitizeUserString($array['background_color']); if (!$this->_checkColorHexCode($array['background_color'])) { $this->setAPIResponse('error', 'Tab background color is invalid', 422); return false; } } if (array_key_exists('text_color', $array)) { + $array['text_color'] = $this->sanitizeUserString($array['text_color']); if (!$this->_checkColorHexCode($array['text_color'])) { $this->setAPIResponse('error', 'Tab text color is invalid', 422); return false; } } + if (array_key_exists('image', $array)) { + $array['image'] = $this->sanitizeUserString($array['image']); + } $response = [ array( 'function' => 'query', @@ -871,6 +882,7 @@ public function _addCategory($array) $array['order'] = ($array['order']) ?? $this->_getNextBookmarkCategoryOrder() + 1; $array['category_id'] = ($array['category_id']) ?? $this->_getNextBookmarkCategoryId() + 1; if (array_key_exists('category', $array)) { + $array['category'] = $this->sanitizeUserString($array['category']); if ($this->_isBookmarkCategoryNameTaken($array['category'])) { $this->setAPIResponse('error', 'Category name: ' . $array['category'] . ' is already taken', 409); return false; @@ -913,6 +925,7 @@ public function _updateCategory($id, $array) return false; } if (array_key_exists('category', $array)) { + $array['category'] = $this->sanitizeUserString($array['category']); if ($this->_isBookmarkCategoryNameTaken($array['category'], $id)) { $this->setAPIResponse('error', 'Category name: ' . $array['category'] . ' is already taken', 409); return false;