CVE-2021-43091 (published 2022-03-25T17:15Z)

An SQL Injection vlnerability exits in Yeswiki doryphore 20211012 via the email parameter in the registration form.

Severity: MEDIUM
CVSS v2 base score: 5.0 (AV:N/AC:L/Au:N/C:P/I:N/A:N)
CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)

Weakness information:
cwe_id: CWE-89
cwe_name: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
description: The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
extended_description: 
            
            
         
         

Fix information:
repo_url: https://github.com/yeswiki/yeswiki
commit_details: repo_url: https://github.com/yeswiki/yeswiki
author: Jérémy Dufraisse
author_date: 2021-10-20 01:36:49+02:00
msg: fix(SQL query): use in all case escape to format query
repository: repo_url: https://github.com/yeswiki/yeswiki
repo_name: YesWiki/yeswiki
description: YesWiki is a wiki system written in PHP, including extensions making collaboration more simple (databases, maps, easy editing, bootstrap themes,...).
repo_language: PHP
owner: yeswiki
file_changes: filename: listpages.php
change_type: ModificationType.MODIFY
diff: @@ -115,7 +115,7 @@ if ($tree) {
             $links[$tree] = array();
     } // switch
     if ($sort != 'tag') {
-        $sql .= ' WHERE a.tag = "' . AddSlashes($tree) . '" AND a.latest = "Y" LIMIT 1';
+        $sql .= ' WHERE a.tag = "' . $this->services->get(\YesWiki\Core\Service\DbService::class)->escape($tree) . '" AND a.latest = "Y" LIMIT 1';
         if (!$rootData = $this->LoadSingle($sql)) {
             echo '<div class="alert alert-danger"><strong>'._t('ERROR').' '._t('ACTION').' ListPages</strong> : '._('THE_PAGE').' ' . htmlspecialchars($tree, ENT_COMPAT, YW_CHARSET) . ' '._t('DOESNT_EXIST').' !</div>';
             return;
@@ -132,8 +132,8 @@ if ($tree) {
     
     // to avoid many loops and computing several time the lists needed for the request,
     // we store them into variables
-    $from = '"' . AddSlashes($tree) . '"';
-    $exclude[] = AddSlashes($tree);
+    $from = '"' . $this->services->get(\YesWiki\Core\Service\DbService::class)->escape($tree) . '"';
+    $exclude[] = $this->services->get(\YesWiki\Core\Service\DbService::class)->escape($tree);
     $exclude_str = '"' . implode('", "', $exclude) . '"';
     for ($i = 1; $i <= $levels; $i++) {
         if ($from) {
@@ -151,7 +151,7 @@ if ($tree) {
                 $sql .= ' WHERE from_tag IN (' . $from . ')'
                     . ' AND to_tag NOT IN (' . $from . ')'
                     . ' AND to_tag = a.tag'
-                    . ' AND a.owner = "' . AddSlashes($owner) . '"'
+                    . ' AND a.owner = "' . $this->services->get(\YesWiki\Core\Service\DbService::class)->escape($owner) . '"'
                     . ' AND a.latest = "Y"';
             } else {
                 $sql = 'SELECT from_tag, to_tag, a.tag IS NOT NULL page_exists';
@@ -208,7 +208,7 @@ if ($tree) {
             $from = '';
             $newworkingon = array();
             foreach ($pages as $page) {
-                $to_tag = '"' . AddSlashes($page['to_tag']) . '"';
+                $to_tag = '"' . $this->services->get(\YesWiki\Core\Service\DbService::class)->escape($page['to_tag']) . '"';
                 $workingon[$page['from_tag']][$page['to_tag']] = array('page_exists' => $page['page_exists'], 'haslinksto' => array());
                 if ($sort != 'tag') {
                     $workingon[$page['from_tag']][$page['to_tag']][$sort] = $page[$sort];
@@ -316,9 +316,9 @@ if ($tree) {
             LEFT JOIN ' . $prefix . 'users ON b.user = name
             LEFT JOIN ' . $prefix . 'pages user_page ON name = user_page.tag AND user_page.latest = "Y"'
             . ($owner ? '' : ' LEFT JOIN ' . $prefix . 'pages owner_page ON b.owner = owner_page.tag AND owner_page.latest = "Y"')
-            . ' WHERE a.user = "' . AddSlashes($user) . '"'
+            . ' WHERE a.user = "' . $this->services->get(\YesWiki\Core\Service\DbService::class)->escape($user) . '"'
             . ' AND a.tag = b.tag AND b.latest = "Y"'
-            . ($owner ? ' AND b.owner = "' . AddSlashes($owner) . '"' : '');
+            . ($owner ? ' AND b.owner = "' . $this->services->get(\YesWiki\Core\Service\DbService::class)->escape($owner) . '"' : '');
     } elseif ($owner) {
         if ($sort == 'user') {
             $sql = 'SELECT a.tag, a.time,
@@ -329,7 +329,7 @@ if ($tree) {
         } else {
             $sql = 'SELECT tag, time FROM ' . $prefix . 'pages a';
         }
-        $sql .= ' WHERE a.owner = "' . AddSlashes($owner) . '" AND a.latest = "Y"';
+        $sql .= ' WHERE a.owner = "' . $this->services->get(\YesWiki\Core\Service\DbService::class)->escape($owner) . '" AND a.latest = "Y"';
     } else {
         if ($sort == 'user') {
             $sql = 'SELECT a.tag, a.owner,

programming_language: PHP
filename: newtextsearch.php
change_type: ModificationType.MODIFY
diff: @@ -148,7 +148,7 @@ if ($phrase) {
     
     // Modification de caractère spéciaux
     $phraseFormatted= str_replace(array('*', '?'), array('%', '_'), $phrase);
-    $phraseFormatted = addslashes($phraseFormatted);
+    $phraseFormatted = $this->services->get(\YesWiki\Core\Service\DbService::class)->escape($phraseFormatted);
 
     // Blablabla SQL
     $requestfull = 'SELECT body, tag FROM '.$prefixe.'pages

programming_language: PHP
filename: User.class.php
change_type: ModificationType.MODIFY
diff: @@ -1000,7 +1000,7 @@ class User
     {
         /* Build sql query*/
         $sql  = 'SELECT * FROM '.$this->usersTable;
-        $sql .= ' WHERE email = "'.$email.'";';
+        $sql .= ' WHERE email = "'.mysqli_real_escape_string($this->wiki->dblink,$email).'";';
         /* Execute query */
         $results = $this->wiki->loadAll($sql);
         return $results; // If the password does not already exist in DB, $result is an empty table => false

programming_language: PHP
filename: FormManager.php
change_type: ModificationType.MODIFY
diff: @@ -46,7 +46,7 @@ class FormManager
             return $this->cachedForms[$formId];
         }
 
-        $form = $this->dbService->loadSingle('SELECT * FROM ' . $this->dbService->prefixTable('nature') . 'WHERE bn_id_nature=\'' . $formId . '\'');
+        $form = $this->dbService->loadSingle('SELECT * FROM ' . $this->dbService->prefixTable('nature') . 'WHERE bn_id_nature=\'' . $this->dbService->escape($formId) . '\'');
 
         if (!$form) {
             return null;
@@ -105,13 +105,13 @@ class FormManager
         return $this->dbService->query('INSERT INTO ' . $this->dbService->prefixTable('nature')
             . '(`bn_id_nature` ,`bn_ce_i18n` ,`bn_label_nature` ,`bn_template` ,`bn_description` ,`bn_sem_context` ,`bn_sem_type` ,`bn_sem_use_template` ,`bn_condition`)'
             . ' VALUES (' . $data['bn_id_nature'] . ', "fr-FR", "'
-            . addslashes(_convert($data['bn_label_nature'], YW_CHARSET, true)) . '","'
-            . addslashes(_convert($data['bn_template'], YW_CHARSET, true)) . '", "'
-            . addslashes(_convert($data['bn_description'], YW_CHARSET, true)) . '", "'
-            . addslashes(_convert($data['bn_sem_context'], YW_CHARSET, true)) . '", "'
-            . addslashes(_convert($data['bn_sem_type'], YW_CHARSET, true)) . '", '
+            . $this->dbService->escape(_convert($data['bn_label_nature'], YW_CHARSET, true)) . '","'
+            . $this->dbService->escape(_convert($data['bn_template'], YW_CHARSET, true)) . '", "'
+            . $this->dbService->escape(_convert($data['bn_description'], YW_CHARSET, true)) . '", "'
+            . $this->dbService->escape(_convert($data['bn_sem_context'], YW_CHARSET, true)) . '", "'
+            . $this->dbService->escape(_convert($data['bn_sem_type'], YW_CHARSET, true)) . '", '
             . (isset($data['bn_sem_use_template']) ? '1' : '0') . ', "'
-            . addslashes(_convert($data['bn_condition'], YW_CHARSET, true)) . '")');
+            . $this->dbService->escape(_convert($data['bn_condition'], YW_CHARSET, true)) . '")');
     }
 
     public function update($data)
@@ -120,14 +120,14 @@ class FormManager
             throw new \Exception(_t('WIKI_IN_HIBERNATION'));
         }
         return $this->dbService->query('UPDATE' . $this->dbService->prefixTable('nature') . 'SET '
-            . '`bn_label_nature`="' . addslashes(_convert($data['bn_label_nature'], YW_CHARSET, true)) . '" ,'
-            . '`bn_template`="' . addslashes(_convert($data['bn_template'], YW_CHARSET, true)) . '" ,'
-            . '`bn_description`="' . addslashes(_convert($data['bn_description'], YW_CHARSET, true)) . '" ,'
-            . '`bn_sem_context`="' . addslashes(_convert($data['bn_sem_context'], YW_CHARSET, true)) . '" ,'
-            . '`bn_sem_type`="' . addslashes(_convert($data['bn_sem_type'], YW_CHARSET, true)) . '" ,'
+            . '`bn_label_nature`="' . $this->dbService->escape(_convert($data['bn_label_nature'], YW_CHARSET, true)) . '" ,'
+            . '`bn_template`="' . $this->dbService->escape(_convert($data['bn_template'], YW_CHARSET, true)) . '" ,'
+            . '`bn_description`="' . $this->dbService->escape(_convert($data['bn_description'], YW_CHARSET, true)) . '" ,'
+            . '`bn_sem_context`="' . $this->dbService->escape(_convert($data['bn_sem_context'], YW_CHARSET, true)) . '" ,'
+            . '`bn_sem_type`="' . $this->dbService->escape(_convert($data['bn_sem_type'], YW_CHARSET, true)) . '" ,'
             . '`bn_sem_use_template`=' . (isset($data['bn_sem_use_template']) ? '1' : '0') . ' ,'
-            . '`bn_condition`="' . addslashes(_convert($data['bn_condition'], YW_CHARSET, true)) . '"'
-            . ' WHERE `bn_id_nature`=' . $data['bn_id_nature']);
+            . '`bn_condition`="' . $this->dbService->escape(_convert($data['bn_condition'], YW_CHARSET, true)) . '"'
+            . ' WHERE `bn_id_nature`=' . $this->dbService->escape($data['bn_id_nature']));
     }
 
     public function clone($id)
@@ -155,7 +155,7 @@ class FormManager
         }
 
         $this->clear($id);
-        return $this->dbService->query('DELETE FROM ' . $this->dbService->prefixTable('nature') . 'WHERE bn_id_nature=' . $id);
+        return $this->dbService->query('DELETE FROM ' . $this->dbService->prefixTable('nature') . 'WHERE bn_id_nature=' . $this->dbService->escape($id));
     }
 
     public function clear($id)
@@ -167,14 +167,14 @@ class FormManager
             'DELETE FROM' . $this->dbService->prefixTable('acls') .
             'WHERE page_tag IN (SELECT tag FROM ' . $this->dbService->prefixTable('pages') .
             'WHERE tag IN (SELECT resource FROM ' . $this->dbService->prefixTable('triples') .
-            'WHERE property="http://outils-reseaux.org/_vocabulary/type" AND value="fiche_bazar") AND body LIKE \'%"id_typeannonce":"' . $id . '"%\' );'
+            'WHERE property="http://outils-reseaux.org/_vocabulary/type" AND value="fiche_bazar") AND body LIKE \'%"id_typeannonce":"' . $this->dbService->escape($id) . '"%\' );'
         );
 
         // TODO use PageManager
         $this->dbService->query(
             'DELETE FROM' . $this->dbService->prefixTable('pages') .
             'WHERE tag IN (SELECT resource FROM ' . $this->dbService->prefixTable('triples') .
-            'WHERE property="http://outils-reseaux.org/_vocabulary/type" AND value="fiche_bazar") AND body LIKE \'%"id_typeannonce":"' . $id . '"%\';'
+            'WHERE property="http://outils-reseaux.org/_vocabulary/type" AND value="fiche_bazar") AND body LIKE \'%"id_typeannonce":"' . $this->dbService->escape($id) . '"%\';'
         );
 
         // TODO use TripleStore

programming_language: PHP
filename: despam.php
change_type: ModificationType.MODIFY
diff: @@ -62,7 +62,7 @@ if ($this->UserIsAdmin()) {
               "select *
               from ".$this->config["table_prefix"]."pages
               where
-              time > date_sub(now(), interval " . addslashes($_POST['from']) . " hour)
+              time > date_sub(now(), interval " . $this->services->get(\YesWiki\Core\Service\DbService::class)->escape($_POST['from']) . " hour)
               and latest = 'Y'
               order by `time` desc";
             $title =

programming_language: PHP