diff --git a/config.xml b/config.xml
index b916712..71d76d6 100644
--- a/config.xml
+++ b/config.xml
@@ -2,11 +2,11 @@
securitylite
-
+
1
0
-
+
\ No newline at end of file
diff --git a/securitylite.php b/securitylite.php
index 19165f8..c3fc891 100644
--- a/securitylite.php
+++ b/securitylite.php
@@ -23,7 +23,7 @@ public function __construct()
{
$this->name = 'securitylite';
$this->tab = 'administration';
- $this->version = '2.0.0';
+ $this->version = '3.0.0';
$this->author = 'Mathias Reker';
$this->module_key = '';
$this->need_instance = 0;
@@ -41,8 +41,6 @@ public function install()
{
include _PS_MODULE_DIR_ . $this->name . '/sql/install.php';
- $this->checkHtaccess();
-
Configuration::updateValue('LITE_BAN_TIME', 30);
Configuration::updateValue('LITE_MAX_RETRY', 5);
Configuration::updateValue('LITE_FIND_TIME', 10);
@@ -64,11 +62,6 @@ public function uninstall()
foreach (array_keys($form_values) as $key) {
Configuration::deleteByName($key);
}
- $file = _PS_ROOT_DIR_ . '/.htaccess';
-
- if (file_exists($file)) {
- $this->removeHtaccessContent($file);
- }
return parent::uninstall();
}
@@ -78,13 +71,7 @@ public function getContent()
$out = null;
$url = 'https://addons.prestashop.com/en/website-security-access/44413-security-pro.html';
-
- if (isset($_SERVER['HTACCESS'])) {
- $out .= $this->displayInformation($this->l('All features in') . ' Security Pro ' . $this->l('will work on your setup!') . ' (' .
- $_SERVER['SERVER_SOFTWARE'] . ')');
- } else {
- $out .= $this->displayInformation($this->l('Some features in') . ' Security Pro ' . $this->l('might not work on your setup, because your .htaccess file is not used!') . ' (' . $_SERVER['SERVER_SOFTWARE'] . ')');
- }
+ $out .= $this->displayInformation($this->l('To unlock pro features, buy pro version:') . ' Security Pro ');
if ((bool) Tools::isSubmit('submitSecurityLiteModule')) {
$this->postProcess();
@@ -129,26 +116,82 @@ public function getContent()
return $out . $this->renderForm() . $this->checkSystem() . $this->securityPro();
}
- public function checkHtaccess()
+ private function chmodFileDir($dir)
{
- $Prestashop_closing = '# ~~end~~ Do not remove this comment, Prestashop will keep automatically the code outside this comment when .htaccess will be generated again';
- $security_lite_starts = '# ~security_lite~';
- $current = 'SetEnv HTACCESS on';
- $security_lite_ends = '# ~security_lite_end~';
+ if (Configuration::get('LITE_PERMISSIONS')) {
+ $perms = [];
+ $perms['file'] = 0644;
+ $perms['directory'] = 0755;
+ $error_dir = null;
+ $error_file = null;
+ $dh = @opendir($dir);
- if (!$htaccess_content = Tools::file_get_contents(_PS_ROOT_DIR_ . '/.htaccess')) {
- Tools::generateHtaccess();
- $htaccess_content = Tools::file_get_contents(_PS_ROOT_DIR_ . '/.htaccess');
+ if ($dh) {
+ while (false !== ($file = readdir($dh))) {
+ if ('.' !== $file && '..' !== $file) {
+ $fullpath = $dir . '/' . $file;
+
+ if (!is_dir($fullpath)) {
+ if (!chmod($fullpath, $perms['file'])) {
+ $error_file .= '' . $this->l('Failed') . ' ' . $this->l('to set file permissions on') . ' ' . $fullpath . PHP_EOL;
+ }
+ } else {
+ if (chmod($fullpath, $perms['directory'])) {
+ $this->chmodFileDir($fullpath);
+ } else {
+ $error_dir .= '' . $this->l('Failed') . ' ' . $this->l('to set directory permissions on') . ' ' . $fullpath . PHP_EOL;
+ }
+ }
+ }
+ }
+ closedir($dh);
+ }
}
- $content_to_add = $security_lite_starts . PHP_EOL . $current . PHP_EOL . $security_lite_ends;
+ }
- if (preg_match('/\# ~security_lite~(.*?)\# ~security_lite_end~/s', $htaccess_content, $m)) {
- $content_to_remove = $m[0];
- $htaccess_content = str_replace($content_to_remove, $content_to_add, $htaccess_content);
- } else {
- $htaccess_content = str_replace($Prestashop_closing, $Prestashop_closing . PHP_EOL . PHP_EOL . $content_to_add, $htaccess_content);
+ private function blockIp()
+ {
+ if (Configuration::get('LITE_BAN_IP_ACTIVATE') && '' !== Configuration::get('LITE_BAN_IP')) {
+ $deny = explode(',', preg_replace('/\s+/', '', Configuration::get('LITE_BAN_IP')));
+
+ if (in_array($_SERVER['REMOTE_ADDR'], $deny)) {
+ header('HTTP/1.1 403 Forbidden');
+
+ die;
+ }
}
- file_put_contents(_PS_ROOT_DIR_ . '/.htaccess', $htaccess_content);
+ }
+
+ private function ban()
+ {
+ $this->context->employee->logout();
+
+ die('Banned');
+ }
+
+ private function getBanTime($email)
+ {
+ $sql = new DbQuery();
+ $sql->select('MAX(access_time) AS access_time');
+ $sql->from('securitylite');
+ $sql->where('banned = 1');
+ $sql->where(sprintf('email = "%s"', pSQL($email)));
+ $sqlResult = Db::getInstance()->executeS($sql);
+
+ return $sqlResult ? strtotime($sql) : 0;
+ }
+
+ private function getEldestAccessTry($email)
+ {
+ $maxRetry = (int) ConfigurationCore::get('LITE_MAX_RETRY');
+ $email = pSQL($email);
+ $query = 'SELECT IF(COUNT(*) = ' . $maxRetry .
+ ', MIN(access_time), \'0000-00-00 00:00:00\') AS access_time FROM (SELECT access_time FROM ' .
+ _DB_PREFIX_ . 'securitylite WHERE banned = 0 AND email = "' .
+ $email . '" ORDER BY access_time DESC LIMIT ' . $maxRetry . ') tmp';
+ $accessStats = Db::getInstance()->getRow($query);
+
+ return $accessStats ? strtotime($accessStats['access_time']) : 0;
}
public function hookDisplayHeader($params)
@@ -242,142 +285,6 @@ public function securityPro()
$this->name . '/views/img/security-scan.png">';
}
- public function checkSystem()
- {
- $pro_feature = '' . $this->l('PRO FEATURE!') . '';
- $helper_list = new HelperList();
- $helper_list->module = $this;
- $helper_list->title = $this->l('Scans your system for known security vulnerabilities and recommends options for increased protection');
- $helper_list->shopLinkType = '';
- $helper_list->no_link = true;
- $helper_list->show_toolbar = true;
- $helper_list->simple_header = false;
- $helper_list->currentIndex = $this->context->link->getAdminLink('AdminModules', false) .
- '&configure=' . $this->name;
- $helper_list->token = Tools::getAdminTokenLite('AdminModules');
- $check = '';
- $vulnerable = '';
- $fields_list = [
- 'check' => [
- 'title' => '' . $this->l('Check') . '',
- 'search' => false,
- 'float' => true,
- ],
- 'status' => [
- 'title' => '' . $this->l('Status') . '',
- 'search' => false,
- 'float' => true,
- ],
- 'fix' => [
- 'title' => '' . $this->l('How to fix') . '',
- 'search' => false,
- 'float' => true,
- ],
- ];
- $result = [
- [
- 'check' => '' . $this->l('CVE-2018-19355') . '',
- 'status' => file_exists(_PS_MODULE_DIR_ . 'orderfiles/upload.php') ? $vulnerable : $check,
- 'fix' => $this->l('Upgrade PrestaShop to latest version'),
- ],
- [
- 'check' => 'CVE-2018-19124, ' .
- 'CVE-2018-19125, ' .
- 'CVE-2018-19126',
- 'status' => 1 == $this->checkCVE201819126() ? $vulnerable : $check,
- 'fix' => $this->l('Set') . ' "phar.readonly = Off" ' . $this->l('in file') . ': ' . php_ini_loaded_file(),
- ],
- [
- 'check' => 'CVE-2018-13784',
- 'status' => 1 == version_compare(_PS_VERSION_, '1.7.3.4', '<') ? $vulnerable : $check,
- 'fix' => $this->l('Upgrade PrestaShop to latest version'),
- ],
- [
- 'check' => 'CVE-2018-8823, ' .
- 'CVE-2018-8824',
- 'status' => 1 == $this->checkCVE20188824() ? $vulnerable : $check,
- 'fix' => $this->l('Upgrade module: Responsive Mega Menu (Horizontal+Vertical+Dropdown) Pro'),
- ],
- [
- 'check' => 'CVE-2018-7491',
- 'status' => 1 == $this->checkCVE20187491() ? $vulnerable : $check,
- 'fix' => $this->l('Enable "Click-jack protection" in "Secure FO" above'),
- ],
- [
- 'check' => $this->l('PHP version') . ' (' . PHP_VERSION . ')',
- 'status' => $pro_feature,
- 'fix' => $pro_feature,
- ],
- [
- 'check' => $this->l('PHP information leakage (version)'),
- 'status' => $pro_feature,
- 'fix' => $pro_feature,
- ],
- [
- 'check' => $this->l('PHP information leakage (logs)'),
- 'status' => $pro_feature,
- 'fix' => $pro_feature,
- ],
- [
- 'check' => $this->l('SSL enabled'),
- 'status' => $pro_feature,
- 'fix' => $pro_feature,
- ],
- [
- 'check' => $this->l('SSL Enabled everywhere'),
- 'status' => $pro_feature,
- 'fix' => $pro_feature,
- ],
- [
- 'check' => $this->l('PrestaShop token'),
- 'status' => $pro_feature,
- 'fix' => $pro_feature,
- ],
- [
- 'check' => 'mod_security',
- 'status' => $pro_feature,
- 'fix' => $pro_feature,
- ],
- [
- 'check' => 'phpinfo.php',
- 'status' => $pro_feature,
- 'fix' => $pro_feature,
- ],
- [
- 'check' => 'phppsinfo.php',
- 'status' => $pro_feature,
- 'fix' => $pro_feature,
- ],
- [
- 'check' => 'robots.txt',
- 'status' => $pro_feature,
- 'fix' => $pro_feature,
- ],
- [
- 'check' => '.htaccess',
- 'status' => $pro_feature,
- 'fix' => $pro_feature,
- ],
- [
- 'check' => 'PrestaShop admin directory name',
- 'status' => $pro_feature,
- 'fix' => $pro_feature,
- ],
- [
- 'check' => $this->l('Database table prefix'),
- 'status' => $pro_feature,
- 'fix' => $pro_feature,
- ],
- [
- 'check' => $this->l('PrestaShop debug mode'),
- 'status' => $pro_feature,
- 'fix' => $pro_feature,
- ],
- ];
-
- return $helper_list->generateList($result, $fields_list);
- }
-
protected function renderForm()
{
$helper = new HelperForm();
@@ -736,27 +643,6 @@ protected function fieldsForm()
],
],
],
- [
- 'tab' => 'secureFrontOffice',
- 'type' => 'switch',
- 'label' => $this->l('Block specific files'),
- 'name' => 'LITE_BLOCK_FILE_EXTENSIONS',
- 'is_bool' => 1,
- 'desc' => $pro_feature . $this->l('Block executing, downloading and reading files with extensions: aspx, bash, bak, dll, exe, git, hg, ini, jsp, log, mdb, out, sql, svn, swp, tar, rar, rdf.'),
- 'disabled' => 1,
- 'values' => [
- [
- 'id' => 'active_on',
- 'value' => 1,
- 'label' => $this->l('Enabled'),
- ],
- [
- 'id' => 'active_off',
- 'value' => 0,
- 'label' => $this->l('Disabled'),
- ],
- ],
- ],
[
'tab' => 'blockIps',
'type' => 'switch',
@@ -1156,93 +1042,9 @@ protected function postProcess()
}
}
- private function removeHtaccessContent($path)
- {
- $htaccess_content = Tools::file_get_contents($path);
-
- if (preg_match('/\# ~security_lite~(.*?)\# ~security_lite_end~/s', $htaccess_content, $m)) {
- $content_to_remove = $m[0];
- $htaccess_content = str_replace($content_to_remove, '', $htaccess_content);
- }
- file_put_contents($path, $htaccess_content);
- }
-
- private function chmodFileDir($dir)
- {
- if (Configuration::get('LITE_PERMISSIONS')) {
- $perms = [];
- $perms['file'] = 0644;
- $perms['directory'] = 0755;
- $error_dir = null;
- $error_file = null;
- $dh = @opendir($dir);
-
- if ($dh) {
- while (false !== ($file = readdir($dh))) {
- if ('.' !== $file && '..' !== $file) {
- $fullpath = $dir . '/' . $file;
-
- if (!is_dir($fullpath)) {
- if (!chmod($fullpath, $perms['file'])) {
- $error_file .= '' . $this->l('Failed') . ' ' . $this->l('to set file permissions on') . ' ' . $fullpath . PHP_EOL;
- }
- } else {
- if (chmod($fullpath, $perms['directory'])) {
- $this->chmodFileDir($fullpath);
- } else {
- $error_dir .= '' . $this->l('Failed') . ' ' . $this->l('to set directory permissions on') . ' ' . $fullpath . PHP_EOL;
- }
- }
- }
- }
- closedir($dh);
- }
- }
- }
-
- private function blockIp()
+ public function checkCVE201913461()
{
- if (Configuration::get('LITE_BAN_IP_ACTIVATE') && '' !== Configuration::get('LITE_BAN_IP')) {
- $deny = explode(',', preg_replace('/\s+/', '', Configuration::get('LITE_BAN_IP')));
-
- if (in_array($_SERVER['REMOTE_ADDR'], $deny)) {
- header('HTTP/1.1 403 Forbidden');
-
- die;
- }
- }
- }
-
- private function ban()
- {
- $this->context->employee->logout();
-
- die('Banned');
- }
-
- private function getBanTime($email)
- {
- $sql = new DbQuery();
- $sql->select('MAX(access_time) AS access_time');
- $sql->from('securitylite');
- $sql->where('banned = 1');
- $sql->where(sprintf('email = "%s"', pSQL($email)));
- $sqlResult = Db::getInstance()->executeS($sql);
-
- return $sqlResult ? strtotime($sql) : 0;
- }
-
- private function getEldestAccessTry($email)
- {
- $maxRetry = (int) ConfigurationCore::get('LITE_MAX_RETRY');
- $email = pSQL($email);
- $query = 'SELECT IF(COUNT(*) = ' . $maxRetry .
- ', MIN(access_time), \'0000-00-00 00:00:00\') AS access_time FROM (SELECT access_time FROM ' .
- _DB_PREFIX_ . 'securitylite WHERE banned = 0 AND email = "' .
- $email . '" ORDER BY access_time DESC LIMIT ' . $maxRetry . ') tmp';
- $accessStats = Db::getInstance()->getRow($query);
-
- return $accessStats ? strtotime($accessStats['access_time']) : 0;
+ return version_compare(_PS_VERSION_, '1.7.6.0', '<');
}
private function checkCVE20187491()
@@ -1263,6 +1065,11 @@ private function checkCVE20187491()
}
}
+ public function checkCVE201911876()
+ {
+ return is_dir(_PS_ROOT_DIR_ . '/install');
+ }
+
private function checkCVE201819126()
{
if (version_compare(_PS_VERSION_, '1.7.4.4', '<')) {
@@ -1289,4 +1096,155 @@ private function checkCVE20188824()
}
}
}
+
+ public function checkSystem()
+ {
+ $pro_feature = '' . $this->l('PRO FEATURE!') . '';
+ $helper_list = new HelperList();
+ $helper_list->module = $this;
+ $helper_list->title = $this->l('Scans your system for known security vulnerabilities and recommends options for increased protection');
+ $helper_list->shopLinkType = '';
+ $helper_list->no_link = true;
+ $helper_list->show_toolbar = true;
+ $helper_list->simple_header = false;
+ $helper_list->currentIndex = $this->context->link->getAdminLink('AdminModules', false) .
+ '&configure=' . $this->name;
+ $helper_list->token = Tools::getAdminTokenLite('AdminModules');
+ $check = '';
+ $vulnerable = '';
+ $fields_list = [
+ 'check' => [
+ 'title' => '' . $this->l('Check') . '',
+ 'search' => false,
+ 'float' => true,
+ ],
+ 'status' => [
+ 'title' => '' . $this->l('Status') . '',
+ 'search' => false,
+ 'float' => true,
+ ],
+ 'fix' => [
+ 'title' => '' . $this->l('How to fix') . '',
+ 'search' => false,
+ 'float' => true,
+ ],
+ ];
+ $result = [
+ [
+ 'check' => 'CVE-2019-13461',
+ 'status' => $this->checkCVE201913461() ? $vulnerable : $check,
+ 'fix' => $this->l('Upgrade PrestaShop to latest version'),
+ ],
+ [
+ 'check' => 'CVE-2019-11876',
+ 'status' => $this->checkCVE201911876() ? $vulnerable : $check,
+ 'fix' => $this->l('Delete folder') . ': ' . _PS_ROOT_DIR_ . '/install', //fix
+ ],
+ [
+ 'check' => '' . $this->l('CVE-2018-19355') . '',
+ 'status' => file_exists(_PS_MODULE_DIR_ . 'orderfiles/upload.php') ? $vulnerable : $check,
+ 'fix' => $this->l('Upgrade PrestaShop to latest version'),
+ ],
+ [
+ 'check' => 'CVE-2018-19124, ' .
+ 'CVE-2018-19125, ' .
+ 'CVE-2018-19126',
+ 'status' => 1 == $this->checkCVE201819126() ? $vulnerable : $check,
+ 'fix' => $this->l('Set') . ' "phar.readonly = Off" ' . $this->l('in file') . ': ' . php_ini_loaded_file(),
+ ],
+ [
+ 'check' => 'CVE-2018-13784',
+ 'status' => 1 == version_compare(_PS_VERSION_, '1.7.3.4', '<') ? $vulnerable : $check,
+ 'fix' => $this->l('Upgrade PrestaShop to latest version'),
+ ],
+ [
+ 'check' => 'CVE-2018-8823, ' .
+ 'CVE-2018-8824',
+ 'status' => 1 == $this->checkCVE20188824() ? $vulnerable : $check,
+ 'fix' => $this->l('Upgrade module: Responsive Mega Menu (Horizontal+Vertical+Dropdown) Pro'),
+ ],
+ [
+ 'check' => 'CVE-2018-7491',
+ 'status' => 1 == $this->checkCVE20187491() ? $vulnerable : $check,
+ 'fix' => $this->l('Enable "Click-jack protection" in "Secure FO" above'),
+ ],
+ [
+ 'check' => $this->l('PHP version') . ' (' . PHP_VERSION . ')',
+ 'status' => $pro_feature,
+ 'fix' => $pro_feature,
+ ],
+ [
+ 'check' => $this->l('PHP information leakage (version)'),
+ 'status' => $pro_feature,
+ 'fix' => $pro_feature,
+ ],
+ [
+ 'check' => $this->l('PHP information leakage (logs)'),
+ 'status' => $pro_feature,
+ 'fix' => $pro_feature,
+ ],
+ [
+ 'check' => $this->l('Secure cookies'),
+ 'status' => $pro_feature,
+ 'fix' => $pro_feature,
+ ],
+ [
+ 'check' => $this->l('Cookie HTTP only'),
+ 'status' => $pro_feature,
+ 'fix' => $pro_feature,
+ ],
+ [
+ 'check' => $this->l('SSL enabled'),
+ 'status' => $pro_feature,
+ 'fix' => $pro_feature,
+ ],
+ [
+ 'check' => $this->l('SSL Enabled everywhere'),
+ 'status' => $pro_feature,
+ 'fix' => $pro_feature,
+ ],
+ [
+ 'check' => $this->l('PrestaShop token'),
+ 'status' => $pro_feature,
+ 'fix' => $pro_feature,
+ ],
+ [
+ 'check' => 'mod_security',
+ 'status' => $pro_feature,
+ 'fix' => $pro_feature,
+ ],
+ [
+ 'check' => 'phpinfo.php',
+ 'status' => $pro_feature,
+ 'fix' => $pro_feature,
+ ],
+ [
+ 'check' => 'phppsinfo.php',
+ 'status' => $pro_feature,
+ 'fix' => $pro_feature,
+ ],
+ [
+ 'check' => 'robots.txt',
+ 'status' => $pro_feature,
+ 'fix' => $pro_feature,
+ ],
+ [
+ 'check' => 'PrestaShop admin directory name',
+ 'status' => $pro_feature,
+ 'fix' => $pro_feature,
+ ],
+ [
+ 'check' => $this->l('Database table prefix'),
+ 'status' => $pro_feature,
+ 'fix' => $pro_feature,
+ ],
+ [
+ 'check' => $this->l('PrestaShop debug mode'),
+ 'status' => $pro_feature,
+ 'fix' => $pro_feature,
+ ],
+ ];
+
+ return $helper_list->generateList($result, $fields_list);
+ }
}