diff --git a/README.md b/README.md index 5f8b625..d8b73fb 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,16 @@ ![LabelGrup Logo](logo.png) -Module for PrestaShop <1.7.8.9 to fix CVE-2023-30839 vulnerability (SQL Injection) +Module for PrestaShop <1.7.8.9 to fix CVE-2023-30545, CVE-2023-30839 and CVE-2023-30839 vulnerabilities For further information, check the following links: +- CVE: https://nvd.nist.gov/vuln/detail/CVE-2023-30545 +- CVE: https://nvd.nist.gov/vuln/detail/CVE-2023-30838 - CVE: https://nvd.nist.gov/vuln/detail/CVE-2023-30839 + +- GitHub: https://github.com/PrestaShop/PrestaShop/security/advisories/GHSA-8r4m-5p6p-52rp - GitHub: https://github.com/PrestaShop/PrestaShop/security/advisories/GHSA-p379-cxqh-q822 +- GitHub: https://github.com/PrestaShop/PrestaShop/security/advisories/GHSA-fh7r-996q-gvcp **Instructions:** diff --git a/lblfixer_cve_2023_30839.php b/lblfixer_cve_2023_30839.php index 4206b1e..2a056e0 100644 --- a/lblfixer_cve_2023_30839.php +++ b/lblfixer_cve_2023_30839.php @@ -18,17 +18,22 @@ class Lblfixer_cve_2023_30839 extends Module { + private const LBL_PATCHES_DIR = '/patches/'; + private const LBL_BACKUP_DIR = '/backup/'; + private const LBL_PATCH_EXTENSION = '.patch'; + private const LBL_DIR_EXTENSION = '.dir'; + public function __construct() { $this->name = 'lblfixer_cve_2023_30839'; $this->tab = 'front_office_features'; - $this->version = '1.0.0'; + $this->version = '1.1.0'; $this->author = 'LabelGrup Networks SL, Manel Alonso'; $this->need_instance = 0; - $this->displayName = $this->l('LabelGrup.com FIX CVE-2023-30839 (for PrestaShop <1.7.8.9)'); - $this->description = $this->l('Fixes CVE-2023-30839 vulnerability.'); + $this->displayName = $this->l('LabelGrup.com FIX CVE-2023 Pack (for PrestaShop <1.7.8.9)'); + $this->description = $this->l('Fixes CVE-2023-30545, CVE-2023-30838, CVE-2023-30839 vulnerabilities.'); $this->ps_versions_compliancy = array('min' => '1.7.0', 'max' => '1.7.8.8'); - $this->confirmUninstall = $this->l('Your shop will be vulnerable to CVE-2023-30839.') . + $this->confirmUninstall = $this->l('Your shop will be vulnerable to 3 vulnerabilities.') . $this->l('Are you sure you want to uninstall this addon?'); parent::__construct(); @@ -52,11 +57,11 @@ public function uninstall() */ private function getFilePath() { - return _PS_ROOT_DIR_ . _PS_CLASS_DIR_; + return _PS_ROOT_DIR_; } /** - * Apply patch for CVE-2023-30839 + * Apply patches * @return bool */ private function patchCVE() @@ -69,7 +74,7 @@ private function patchCVE() } /** - * Remove patch for CVE-2023-30839 + * Remove patches * @return bool */ private function unpatchCVE() @@ -85,11 +90,18 @@ private function detectAlreadyPatched() { // For each file to patch, check if the patch is already applied $files_to_patch = $this->getFilesToPatch(); - $base_path = $this->getFilePath(); foreach ($files_to_patch as $file_to_patch) { + $base_path = $this->getFilePath(); + $patch_file = dirname(__FILE__) . self::LBL_PATCHES_DIR . $file_to_patch . self::LBL_PATCH_EXTENSION; + $dir_patch_file = $this->getPathForPatch($patch_file); + + if (strlen($dir_patch_file) > 0) { + $base_path = $base_path . $dir_patch_file; + } + $path = $base_path . $file_to_patch; - if ($this->detectAlreadyPatchedFile($path, 'CVE-2023-30839')) { + if ($this->detectAlreadyPatchedFile($path, 'Patch for CVE-')) { return true; } } @@ -118,7 +130,7 @@ private function detectAlreadyPatchedFile($file, $pattern) */ private function getPatchFiles() { - return glob(dirname(__FILE__) . '/patches/*.patch'); + return glob(dirname(__FILE__) . self::LBL_PATCHES_DIR . '*' . self::LBL_PATCH_EXTENSION); } /** @@ -130,7 +142,7 @@ private function getFilesToPatch() $file_pathes = $this->getPatchFiles(); foreach ($file_pathes as $file_path) { $file_name = basename($file_path); - $file_name = str_replace('.patch', '', $file_name); + $file_name = str_replace(self::LBL_PATCH_EXTENSION, '', $file_name); $files[] = $file_name; } return $files; @@ -143,15 +155,8 @@ private function getFilesToPatch() */ private function parsePatchFile($file_path) { - $patches = []; - $file = fopen($file_path, 'r'); - while (!feof($file)) { - $line = fgets($file); - $line_patch = explode('¤', $line); - array_push($patches, $line_patch); - } - - return $patches; + $patches = explode('¤', Tools::file_get_contents($file_path)); + return [$patches]; } /** @@ -161,11 +166,17 @@ private function parsePatchFile($file_path) private function patchFiles() { $files_to_patch = $this->getFilesToPatch(); - $base_path = $this->getFilePath(); foreach ($files_to_patch as $file_to_patch) { + $base_path = $this->getFilePath(); + $patch_file = dirname(__FILE__) . self::LBL_PATCHES_DIR . $file_to_patch . self::LBL_PATCH_EXTENSION; + $dir_patch_file = $this->getPathForPatch($patch_file); + + if (strlen($dir_patch_file) > 0) { + $base_path = $base_path . $dir_patch_file; + } + $path = $base_path . $file_to_patch; - $patch_file = __DIR__ . '/patches/' . $file_to_patch . '.patch'; if (!$this->patchFile($path, $patch_file)) { return false; } @@ -209,7 +220,7 @@ private function patchFile($path, $patch_file) private function backupFile($path) { $filename = basename($path); - if (!@copy($path, dirname(__FILE__) . '/backup/' . $filename)) { + if (!@copy($path, dirname(__FILE__) . self::LBL_BACKUP_DIR . $filename)) { return false; } @@ -227,7 +238,7 @@ private function unpatchFiles() foreach ($files_to_patch as $file_to_patch) { $path = $base_path . $file_to_patch; - $backup_file = __DIR__ . '/backup/' . $file_to_patch; + $backup_file = __DIR__ . self::LBL_BACKUP_DIR . $file_to_patch; if (@copy($backup_file, $path)) { @unlink($backup_file); } @@ -235,4 +246,21 @@ private function unpatchFiles() return true; } + + /** + * Gets the path for a patch + * @param string $patch_file Path to the patch file + * @return string + */ + private function getPathForPatch($patch_file) + { + $first_line = ''; + $dir_file = str_replace(self::LBL_PATCH_EXTENSION, self::LBL_DIR_EXTENSION, $patch_file); + if (file_exists($dir_file)) { + $fdir = fopen($dir_file, 'r'); + $first_line = fgets($fdir); + fclose($fdir); + } + return $first_line; + } } diff --git a/patches/Db.php.dir b/patches/Db.php.dir new file mode 100644 index 0000000..ab10db2 --- /dev/null +++ b/patches/Db.php.dir @@ -0,0 +1 @@ +/classes/db/ \ No newline at end of file diff --git a/patches/Db.php.patch b/patches/Db.php.patch index 15a00c6..4dc656d 100644 --- a/patches/Db.php.patch +++ b/patches/Db.php.patch @@ -7,8 +7,8 @@ return $this->execute($sql, $use_cache); } ¤ - // Patch for CVE-2023-30839 + // Patch for CVE-2023-30838, CVE-2023-30839 // This method must be used only with queries which display results - if (!preg_match('#^\s*\(?\s*(select|show|explain|describe|desc)\s#i', $sql)) { + if (!preg_match('#^\s*\(?\s*(select|show|explain|describe|desc|checksum)\s#i', $sql)) { throw new PrestaShopDatabaseException('Db->executeS() must be used only with select, show, explain or describe queries'); } \ No newline at end of file diff --git a/patches/Validate.php.dir b/patches/Validate.php.dir new file mode 100644 index 0000000..9c9e915 --- /dev/null +++ b/patches/Validate.php.dir @@ -0,0 +1 @@ +/classes/ \ No newline at end of file diff --git a/patches/Validate.php.patch b/patches/Validate.php.patch new file mode 100644 index 0000000..8218a04 --- /dev/null +++ b/patches/Validate.php.patch @@ -0,0 +1,4 @@ + $events .= '|onselectstart|onstart|onstop'; +¤ + // Patch for CVE-2023-30545 + $events .= '|onselectstart|onstart|onstop|onanimationcancel|onanimationend|onanimationiteration|onanimationstart'; \ No newline at end of file