CVE-2022-1514: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Stored XSS via upload plugin functionality in zip format in GitHub repository neorazorx/facturascripts prior to 2022.06. Cross-site scripting attacks can have devastating consequences. Code injected into a vulnerable application can exfiltrate data or install malware on the user's machine. Attackers can masquerade as authorized users via session cookies, allowing them to perform any action allowed by the user account.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 5.4
Published: 2022-04-28T16:15Z
Repository: https://github.com/neorazorx/facturascripts
Language: PHP
Files changed: Core/Base/PluginManager.php
Commit date: 2022-04-27 20:22:59 +0200
Commit message: Sanitized the data read from the ini file to avoid security problems.
------
Saneados los datos leídos del archivo ini para evitar problemas de seguridad.

Diff: diff --git a/Core/Base/PluginManager.php b/Core/Base/PluginManager.php
index 3f923d9a8..3a5d32ecf 100644
--- a/Core/Base/PluginManager.php
+++ b/Core/Base/PluginManager.php
@@ -378,31 +378,36 @@ final class PluginManager
             'min_version' => 0.0,
             'name' => $pluginName,
             'require' => [],
             'version' => 1
         ];
-
         $ini = parse_ini_string($iniContent);
-        if ($ini !== false) {
-            foreach (['name', 'version', 'description', 'min_version'] as $key) {
-                $info[$key] = $ini[$key] ?? $info[$key];
-            }
+        if ($ini === false) {
+            return $info;
+        }
 
-            if (isset($ini['require'])) {
-                $info['require'] = explode(',', $ini['require']);
-            }
+        $info['name'] = strip_tags($ini['name'] ?? $info['name']);
+        $info['version'] = floatval($ini['version'] ?? $info['version']);
+        $info['description'] = strip_tags($ini['description'] ?? $info['description']);
+        $info['min_version'] = floatval($ini['min_version'] ?? $info['min_version']);
 
-            if ($info['min_version'] >= 2018 && $info['min_version'] <= self::CORE_VERSION) {
-                $info['compatible'] = true;
-                $info['description'] = ('Incompatible' === $info['description']) ? ToolBox::i18n()->trans('compatible') : $info['description'];
-            } else {
-                $info['description'] = ToolBox::i18n()->trans('incompatible-with-facturascripts', ['%version%' => self::CORE_VERSION]);
+        if (isset($ini['require'])) {
+            foreach (explode(',', $ini['require']) as $req) {
+                $req = trim($req);
+                if (!empty($req)) {
+                    $info['require'][] = $req;
+                }
             }
+        }
 
-            $info['enabled'] = in_array($info['name'], $this->enabledPlugins());
+        if ($info['min_version'] <= self::CORE_VERSION && $info['min_version'] >= 2020) {
+            $info['compatible'] = true;
+        } else {
+            $info['description'] = ToolBox::i18n()->trans('incompatible-with-facturascripts', ['%version%' => self::CORE_VERSION]);
         }
 
+        $info['enabled'] = in_array($info['name'], $this->enabledPlugins());
         return $info;
     }
 
     /**
      * Returns an array with the list of plugins in the plugin.list file.

Vulnerable code: 
        if ($ini !== false) {
            foreach (['name', 'version', 'description', 'min_version'] as $key) {
                $info[$key] = $ini[$key] ?? $info[$key];
            }
            if (isset($ini['require'])) {
                $info['require'] = explode(',', $ini['require']);
            }
            if ($info['min_version'] >= 2018 && $info['min_version'] <= self::CORE_VERSION) {
                $info['compatible'] = true;
                $info['description'] = ('Incompatible' === $info['description']) ? ToolBox::i18n()->trans('compatible') : $info['description'];
            } else {
                $info['description'] = ToolBox::i18n()->trans('incompatible-with-facturascripts', ['%version%' => self::CORE_VERSION]);
            $info['enabled'] = in_array($info['name'], $this->enabledPlugins());
Fixed code:         if ($ini === false) {
            return $info;
        }
        $info['name'] = strip_tags($ini['name'] ?? $info['name']);
        $info['version'] = floatval($ini['version'] ?? $info['version']);
        $info['description'] = strip_tags($ini['description'] ?? $info['description']);
        $info['min_version'] = floatval($ini['min_version'] ?? $info['min_version']);
        if (isset($ini['require'])) {
            foreach (explode(',', $ini['require']) as $req) {
                $req = trim($req);
                if (!empty($req)) {
                    $info['require'][] = $req;
                }
        }
        if ($info['min_version'] <= self::CORE_VERSION && $info['min_version'] >= 2020) {
            $info['compatible'] = true;
        } else {
            $info['description'] = ToolBox::i18n()->trans('incompatible-with-facturascripts', ['%version%' => self::CORE_VERSION]);
        $info['enabled'] = in_array($info['name'], $this->enabledPlugins());