Skip to content

Commit

Permalink
Initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
malonsolabelgrup committed Apr 27, 2023
1 parent 3e2cc38 commit 1a60b26
Show file tree
Hide file tree
Showing 9 changed files with 338 additions and 1 deletion.
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,18 @@
# lblfixer_cve_2023_30839
# LabelGrup Networks, official PrestaShop Partner

![LabelGrup Logo](logo.png)

Module for PrestaShop <1.7.8.9 to fix CVE-2023-30839 vulnerability (SQL Injection)

For further information, check the following links:
- CVE: https://nvd.nist.gov/vuln/detail/CVE-2023-30839
- GitHub: https://github.com/PrestaShop/PrestaShop/security/advisories/GHSA-p379-cxqh-q822

**Instructions:**

1. Download the latest release from this repository.
2. Install the downloaded ZIP as a normal addon, this will replace/copy the needed files to your current PrestaShop.
3. Be aware: If you remove the addon, your PrestaShop will be reverted to its original state, exposing the vulnerability again.

Visit our website:
https://www.labelgrup.com
1 change: 1 addition & 0 deletions backup/.htaccess
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Deny from all
22 changes: 22 additions & 0 deletions backup/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
/**
* 2023 LabelGrup Networks SL
*
* NOTICE OF LICENSE
*
* READ ATTACHED LICENSE.TXT
*
* @author Manel Alonso <[email protected]>, <[email protected]>
* @copyright 2023 LabelGrup Networks SL
* @license LICENSE.TXT
*/

header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');

header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');

header('Location: ../');
exit;
22 changes: 22 additions & 0 deletions index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
/**
* 2023 LabelGrup Networks SL
*
* NOTICE OF LICENSE
*
* READ ATTACHED LICENSE.TXT
*
* @author Manel Alonso <[email protected]>, <[email protected]>
* @copyright 2023 LabelGrup Networks SL
* @license LICENSE.TXT
*/

header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');

header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');

header('Location: ../');
exit;
238 changes: 238 additions & 0 deletions lblfixer_cve_2023_30839.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
<?php

/**
* 2023 LabelGrup Networks SL
*
* NOTICE OF LICENSE
*
* READ ATTACHED LICENSE.TXT
*
* @author Manel Alonso <[email protected]>, <[email protected]>
* @copyright 2023 LabelGrup Networks SL
* @license LICENSE.TXT
*/

if (!defined('_PS_VERSION_')) {
exit;
}

class Lblfixer_cve_2023_30839 extends Module
{
public function __construct()
{
$this->name = 'lblfixer_cve_2023_30839';
$this->tab = 'front_office_features';
$this->version = '1.0.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->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->l('Are you sure you want to uninstall this addon?');

parent::__construct();
}

public function install()
{
$this->patchCVE();
return parent::install();
}

public function uninstall()
{
$this->unpatchCVE();
return parent::uninstall();
}

/**
* Get the path to the file to patch
* @return string
*/
private function getFilePath()
{
return _PS_ROOT_DIR_ . _PS_CLASS_DIR_;
}

/**
* Apply patch for CVE-2023-30839
* @return bool
*/
private function patchCVE()
{
if ($this->detectAlreadyPatched()) {
return true;
}

return $this->patchFiles();
}

/**
* Remove patch for CVE-2023-30839
* @return bool
*/
private function unpatchCVE()
{
return $this->unpatchFiles();
}

/**
* Detect if the patch is already applied
* @return bool
*/
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) {
$path = $base_path . $file_to_patch;
if ($this->detectAlreadyPatchedFile($path, 'CVE-2023-30839')) {
return true;
}
}

return false;
}

/**
* Detect if the patch is already applied for a file
* @return bool
*/
private function detectAlreadyPatchedFile($file, $pattern)
{
if (file_exists($file)) {
$content = Tools::file_get_contents($file);
if (strpos($content, $pattern) !== false) {
return true;
}
}
return false;
}

/**
* Get the list of files to patch
* @return array
*/
private function getPatchFiles()
{
return glob(dirname(__FILE__) . '/patches/*.patch');
}

/**
* Get the list of files to patch
* @return array
*/
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);
$files[] = $file_name;
}
return $files;
}

/**
* Parse a patch file
* @param string $file_path Path to the patch file
* @return array
*/
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 all files
* @return bool
*/
private function patchFiles()
{
$files_to_patch = $this->getFilesToPatch();
$base_path = $this->getFilePath();

foreach ($files_to_patch as $file_to_patch) {
$path = $base_path . $file_to_patch;
$patch_file = __DIR__ . '/patches/' . $file_to_patch . '.patch';
if (!$this->patchFile($path, $patch_file)) {
return false;
}
}

return true;
}

/**
* Patches a file
* @param string $path Path to the file to patch
* @param string $patch_file Path to the patch file
* @return bool
*/
private function patchFile($path, $patch_file)
{
if (!$this->backupFile($path)) {
return false;
}

$content = Tools::file_get_contents($path);
$patches_for_file = $this->parsePatchFile($patch_file);
foreach ($patches_for_file as $patch) {
$original = $patch[0];
$replacement = $patch[1];
$content = str_replace($original, $replacement, $content);
}

if (!@file_put_contents($path, $content)) {
return false;
}

return true;
}

/**
* Backup the original file
* @param string $path Path to the file to patch
* @return bool
*/
private function backupFile($path)
{
$filename = basename($path);
if (!@copy($path, dirname(__FILE__) . '/backup/' . $filename)) {
return false;
}

return true;
}

/**
* Restore the original files
* @return bool
*/
private function unpatchFiles()
{
$files_to_patch = $this->getFilesToPatch();
$base_path = $this->getFilePath();

foreach ($files_to_patch as $file_to_patch) {
$path = $base_path . $file_to_patch;
$backup_file = __DIR__ . '/backup/' . $file_to_patch;
if (@copy($backup_file, $path)) {
@unlink($backup_file);
}
}

return true;
}
}
Binary file added logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions patches/.htaccess
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Deny from all
14 changes: 14 additions & 0 deletions patches/Db.php.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// 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 (defined('_PS_MODE_DEV_') && _PS_MODE_DEV_) {
throw new PrestaShopDatabaseException('Db->executeS() must be used only with select, show, explain or describe queries');
}

return $this->execute($sql, $use_cache);
}
¤
// Patch for 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)) {
throw new PrestaShopDatabaseException('Db->executeS() must be used only with select, show, explain or describe queries');
}
22 changes: 22 additions & 0 deletions patches/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
/**
* 2023 LabelGrup Networks SL
*
* NOTICE OF LICENSE
*
* READ ATTACHED LICENSE.TXT
*
* @author Manel Alonso <[email protected]>, <[email protected]>
* @copyright 2023 LabelGrup Networks SL
* @license LICENSE.TXT
*/

header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');

header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');

header('Location: ../');
exit;

0 comments on commit 1a60b26

Please sign in to comment.