CVE-2020-10563 (published 2020-03-13T21:15Z)

An issue was discovered in DEVOME GRR before 3.4.1c. frmcontactlist.php mishandles a SQL query.

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

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/JeromeDevome/GRR
commit_details: repo_url: https://github.com/JeromeDevome/GRR
author: yn42
author_date: 2020-03-13 13:24:42+01:00
msg: sous-version 3.4.1c : mise à jour de sécurité
repository: repo_url: https://github.com/JeromeDevome/GRR
repo_name: JeromeDevome/GRR
description: GRR Officiel - Copyright Team DEVOME
repo_language: PHP
owner: JeromeDevome
file_changes: filename: CHANGELOG
change_type: ModificationType.MODIFY
diff: @@ -30,6 +30,9 @@ Sous-version 3.4.1b
 	[correction] divers bugs, erreurs de syntaxe ou orthographiques
 	[modification] limitation de la taille des données conformément à la base
 	[modification] calcul et aspect de la page de contact externe
+Sous-version 3.4.1c
+    [correction] failles de sécurité dans formulaire de contact et gestion des ressources
+    [correction] divers bugs, erreurs de syntaxe ou orthographiques
 -----
 --
 -----

programming_language: Markdown
filename: admin_edit_room.php
change_type: ModificationType.MODIFY
diff: @@ -3,7 +3,7 @@
  * admin_edit_room.php
  * Interface de creation/modification des sites, domaines et des ressources de l'application GRR
  * Ce script fait partie de l'application GRR
- * Dernière modification : $Date: 2020-01-28 11:10$
+ * Dernière modification : $Date: 2020-03-13 12:30$
  * @author    Laurent Delineau & JeromeB & Marc-Henri PAMISEU & Yan Naessens & Daniel Antelme
  * @copyright Copyright 2003-2020 Team DEVOME - JeromeB
  * @link      http://www.gnu.org/licenses/licenses.html
@@ -171,32 +171,38 @@ if ((!empty($room)) || (isset($area_id)))
 	if (isset($change_room))
 	{
 		if (isset($_POST['sup_img']))
-		{
-			$dest = '../images/';
-			$ok1 = false;
-			if ($f = @fopen("$dest/.test", "w"))
-			{
-				@fputs($f, '<'.'?php $ok1 = true; ?'.'>');
-				@fclose($f);
-				include("$dest/.test");
-			}
-			if (!$ok1)
-			{
-				$msg .= "L\'image n\'a pas pu etre supprimee : probleme d\'écriture sur le repertoire. Veuillez signaler ce problème à l\'administrateur du serveur.\\n";
-				$ok = 'no';
-			}
-			else
-			{
-				if (@file_exists($dest."img_".TABLE_PREFIX."".$room.".jpg"))
-					unlink($dest."img_".TABLE_PREFIX."".$room.".jpg");
-				if (@file_exists($dest."img_".TABLE_PREFIX."".$room.".png"))
-					unlink($dest."img_".TABLE_PREFIX."".$room.".png");
-				if (@file_exists($dest."img_".TABLE_PREFIX."".$room.".gif"))
-					unlink($dest."img_".TABLE_PREFIX."".$room.".gif");
-				$picture_room = "";
-			}
-		}
-		if (empty($capacity))
+        {
+            $dest = '../images/';
+            $ok1 = false;
+            if ($f = @fopen("$dest/.test", "w"))
+            {
+                @fputs($f, '<'.'?php $ok1 = true; ?'.'>');
+                @fclose($f);
+                include("$dest/.test");
+            }
+            if (!$ok1)
+            {
+                $msg .= "L\'image n\'a pas pu etre supprimee : probleme d\'écriture sur le repertoire. Veuillez signaler ce problème à l\'administrateur du serveur.\\n";
+                $ok = 'no';
+            }
+            else
+            {
+                if (@file_exists($dest."img_".TABLE_PREFIX."".$room.".jpg"))
+                    unlink($dest."img_".TABLE_PREFIX."".$room.".jpg");
+                if (@file_exists($dest."img_".TABLE_PREFIX."".$room.".png"))
+                    unlink($dest."img_".TABLE_PREFIX."".$room.".png");
+                if (@file_exists($dest."img_".TABLE_PREFIX."".$room.".gif"))
+                    unlink($dest."img_".TABLE_PREFIX."".$room.".gif");
+                // $picture_room = ""; mettre à jour la donnée room
+                $sql_picture = "UPDATE ".TABLE_PREFIX."_room SET picture_room='' WHERE id=".protect_data_sql($room);
+                if (grr_sql_command($sql_picture) < 0)
+                {
+                    fatal_error(0, get_vocab('update_room_failed') . grr_sql_error());
+                    $ok = 'no';
+                }
+            }
+        }
+        if (empty($capacity))
 			$capacity = 0;
 		if ($capacity < 0)
 			$capacity = 0;
@@ -280,65 +286,102 @@ if ((!empty($room)) || (isset($area_id)))
 			$room_name = get_vocab("room")." ".$room;
 			grr_sql_command("UPDATE ".TABLE_PREFIX."_room SET room_name='".protect_data_sql($room_name)."' WHERE id=$room");
 		}
-		$doc_file = isset($_FILES["doc_file"]) ? $_FILES["doc_file"] : NULL;
-		if (preg_match("`\.([^.]+)$`", $doc_file['name'], $match))
-		{
-			$ext = strtolower($match[1]);
-			if ($ext != 'jpg' && $ext != 'png'&& $ext != 'gif')
-			{
-				$msg .= "L\'image n\'a pas pu etre enregistree : les seules extentions autorisees sont gif, png et jpg.\\n";
-				$ok = 'no';
-			}
-			else
-			{
-				$dest = '../images/';
-				$ok1 = false;
-				if ($f = @fopen("$dest/.test", "w"))
-				{
-					@fputs($f, '<'.'?php $ok1 = true; ?'.'>');
-					@fclose($f);
-					include("$dest/.test");
-				}
-				if (!$ok1)
-				{
-					$msg .= "L\'image n\'a pas pu etre enregistree : probleme d\'ecriture sur le repertoire IMAGES. Veuillez signaler ce probleme e l\'administrateur du serveur.\\n";
-					$ok = 'no';
-				}
-				else
-				{
-					$ok1 = @copy($doc_file['tmp_name'], $dest.$doc_file['name']);
-					if (!$ok1)
-						$ok1 = @move_uploaded_file($doc_file['tmp_name'], $dest.$doc_file['name']);
-					if (!$ok1)
-					{
-						$msg .= "L\'image n\'a pas pu etre enregistree : probleme de transfert. Le fichier n\'a pas pu etre transfere sur le repertoire IMAGES. Veuillez signaler ce probleme e l\'administrateur du serveur.\\n";
-						$ok = 'no';
-					}
-					else
-					{
-						$tab = explode(".", $doc_file['name']);
-						$ext = strtolower($tab[1]);
-						if (@file_exists($dest."img_".TABLE_PREFIX."".$room.".".$ext))
-							@unlink($dest."img_".TABLE_PREFIX."".$room.".".$ext);
-						rename($dest.$doc_file['name'],$dest."img_".TABLE_PREFIX."".$room.".".$ext);
-						@chmod($dest."img_".TABLE_PREFIX."".$room.".".$ext, 0666);
-						$picture_room = "img_".TABLE_PREFIX."".$room.".".$ext;
-						$sql_picture = "UPDATE ".TABLE_PREFIX."_room SET picture_room='".protect_data_sql($picture_room)."' WHERE id=".$room;
-						if (grr_sql_command($sql_picture) < 0)
-						{
-							fatal_error(0, get_vocab('update_room_failed') . grr_sql_error());
-							$ok = 'no';
-						}
-					}
-				}
-			}
-		}
-		else if ($doc_file['name'] != '')
-		{
-			$msg .= "L\'image n\'a pas pu etre enregistree : le fichier image selectionne n'est pas valide !\\n";
-			$ok = 'no';
-		}
-		$msg .= get_vocab("message_records");
+        // image d'illustration
+        $doc_file = isset($_FILES["doc_file"]) ? $_FILES["doc_file"] : NULL;
+        /* Test premier, juste pour bloquer les double extensions */
+        if (count(explode('.', $doc_file['name'])) > 2) {
+            $msg .= "L\'image n\'a pas pu être enregistrée : les seules extentions autorisées sont gif, png et jpg.\\n";
+            $ok = 'no';
+        } 
+        elseif  (preg_match("`\.([^.]+)$`", $doc_file['name'], $match)) {
+            $ext = strtolower($match[1]);
+            if ($ext != 'jpg' && $ext != 'png'&& $ext != 'gif')
+            {
+                $msg .= "L\'image n\'a pas pu etre enregistree : les seules extentions autorisees sont gif, png et jpg.\\n";
+                $ok = 'no';
+            }
+            else {
+                /* deuxième test passé, l'extension est autorisée */
+                /* 3ème test avec fileinfo */
+                $finfo = finfo_open(FILEINFO_MIME_TYPE);
+                $fileType = finfo_file($finfo, $doc_file['tmp_name']);
+                /* 4ème test avec gd pour valider que c'est bien une image malgré tout - nécessaire ou parano ? */
+                switch($fileType) {
+                    case "image/gif":
+                        /* recreate l'image, supprime les data exif */
+                        $logoRecreated = @imagecreatefromgif ( $doc_file['tmp_name'] );
+                        /* fix pour la transparence */
+                        imageAlphaBlending($logoRecreated, true);
+                        imageSaveAlpha($logoRecreated, true);
+                        $extSafe = "gif";
+                        break;
+                    case "image/jpeg":
+                        $logoRecreated = @imagecreatefromjpeg ( $doc_file['tmp_name'] );
+                        $extSafe = "jpg";
+                        break;
+                    case "image/png":
+                        $logoRecreated = @imagecreatefrompng ( $doc_file['tmp_name'] );
+                        /* fix pour la transparence */
+                        imageAlphaBlending($logoRecreated, true);
+                        imageSaveAlpha($logoRecreated, true);
+                        $extSafe = "png";
+                        break;
+                    default:
+                        $msg .= "L\'image n\'a pas pu être enregistrée : type mime incompatible.\\n";
+                        $ok = 'no';
+                        $extSafe = false;
+                        break;
+                }
+            }
+            if (!$logoRecreated || $extSafe === false) {
+                /* la fonction imagecreate a échoué, donc l'image est corrompue ou craftée */
+                $msg .= "L\'image n\'a pas pu être enregistrée : fichier corrompu.\\n";
+                $ok = 'no';
+            }
+            else
+            {   /* je teste si la destination est writable */
+                $dest = '../images/';
+                $ok1 = is_writable($dest);
+                if (!$ok1)
+                {
+                    $msg .= "L\'image n\'a pas pu etre enregistree : probleme d\'ecriture sur le repertoire IMAGES. Veuillez signaler ce probleme e l\'administrateur du serveur.\\n";
+                    $ok = 'no';
+                }
+                else
+                {
+                    $ok1 = @copy($doc_file['tmp_name'], $dest.$doc_file['name']);
+                    if (!$ok1)
+                        $ok1 = @move_uploaded_file($doc_file['tmp_name'], $dest.$doc_file['name']);
+                    if (!$ok1)
+                    {
+                        $msg .= "L\'image n\'a pas pu etre enregistree : probleme de transfert. Le fichier n\'a pas pu etre transfere sur le repertoire IMAGES. Veuillez signaler ce probleme à l\'administrateur du serveur.\\n";
+                        $ok = 'no';
+                    }
+                    else
+                    {
+                        $tab = explode(".", $doc_file['name']);
+                        $ext = strtolower($tab[1]);
+                        if (@file_exists($dest."img_".TABLE_PREFIX."".$room.".".$extSafe))
+                            @unlink($dest."img_".TABLE_PREFIX."".$room.".".$extSafe);
+                        rename($dest.$doc_file['name'],$dest."img_".TABLE_PREFIX."".$room.".".$extSafe);
+                        @chmod($dest."img_".TABLE_PREFIX."".$room.".".$extSafe, 0666);
+                        $picture_room = "img_".TABLE_PREFIX."".$room.".".$extSafe;
+                        $sql_picture = "UPDATE ".TABLE_PREFIX."_room SET picture_room='".protect_data_sql($picture_room)."' WHERE id=".protect_data_sql($room);
+                        if (grr_sql_command($sql_picture) < 0)
+                        {
+                            fatal_error(0, get_vocab('update_room_failed') . grr_sql_error());
+                            $ok = 'no';
+                        }
+                    }
+                }
+            }
+        }
+        else if ($doc_file['name'] != '')
+        {
+            $msg .= "L\'image n\'a pas pu etre enregistree : le fichier image selectionne n'est pas valide !\\n";
+            $ok = 'no';
+        }
+        $msg .= get_vocab("message_records");
 	}
 	// Si pas de probleme, retour à la page d'accueil apres enregistrement
 	if ((isset($change_done)) && (!isset($ok)))
@@ -1052,7 +1095,7 @@ if ((!empty($id_area)) || (isset($add_area)))
 		}
 		echo "</select></td>\n";
 		echo "</tr>";
-		// Definition des jours de la semaine e afficher sur les plannings et calendriers
+		// Definition des jours de la semaine à afficher sur les plannings et calendriers
 		echo "<tr>\n";
 		echo "<td>".get_vocab("cocher_jours_a_afficher")."</td>\n";
 		echo "<td>\n";

programming_language: PHP
filename: frmcontactlist.php
change_type: ModificationType.MODIFY
diff: @@ -3,9 +3,9 @@
  * frmcontactlist.php
  * calcule la liste des ressources visibles dans un domaine
  * Ce script fait partie de l'application GRR
- * Dernière modification : $Date: 2018-07-31 16:00$
+ * Dernière modification : $Date: 2020-03-13 11:00$
  * @author    JeromeB & Yan Naessens
- * @copyright Copyright 2003-2018 Team DEVOME - JeromeB
+ * @copyright Copyright 2003-2020 Team DEVOME - JeromeB
  * @link      http://www.gnu.org/licenses/licenses.html
  *
  * This file is part of GRR.
@@ -22,8 +22,9 @@ include "include/misc.inc.php";
 include "include/functions.inc.php";
 
 $id = $_GET['id'];
-// echo "<optgroup label=\"Salles\">"; je supprime optgroup car les ressources ne sont pas toujours des salles ! YN
-$res = grr_sql_query("SELECT room_name,id FROM ".TABLE_PREFIX."_room WHERE area_id = '".$id."' ORDER BY room_name");
+if ($id != protect_data_sql($id))
+    die('Donnée incorrecte');
+$res = grr_sql_query("SELECT room_name,id FROM ".TABLE_PREFIX."_room WHERE area_id = '".protect_data_sql($id)."' ORDER BY room_name");
 $nbresult = mysqli_num_rows($res);
 $user_name = getUserName();
 if ($nbresult != 0)

programming_language: PHP
filename: frmcontactrange.php
change_type: ModificationType.MODIFY
diff: @@ -3,7 +3,7 @@
  * frmcontactrange.php
  * calcule le code html de la partie intervalle du formulaire de contact
  * Ce script fait partie de l'application GRR
- * Dernière modification : $Date: 2020-01-17 14:30$
+ * Dernière modification : $Date: 2020-03-13 11:00$
  * @author    JeromeB & Yan Naessens
  * @copyright Copyright 2003-2020 Team DEVOME - JeromeB
  * @link      http://www.gnu.org/licenses/licenses.html
@@ -22,8 +22,10 @@ include "include/misc.inc.php";
 include "include/functions.inc.php";
 
 $id = $_GET['id'];
+if ($id != protect_data_sql($id))
+    die('Donnée incorrecte');
 $query = "SELECT access,morningstarts_area,eveningends_area,eveningends_minutes_area,enable_periods,resolution_area FROM ".TABLE_PREFIX."_area
-    WHERE id = '".$id."' ";
+    WHERE id = '".protect_data_sql($id)."' ";
 // echo $query."<br />";
 $res = grr_sql_query($query);
 $val= grr_sql_row($res,0);

programming_language: PHP
filename: functions.inc.php
change_type: ModificationType.MODIFY
diff: @@ -2940,7 +2940,7 @@ function send_mail($id_entry, $action, $dformat, $tab_id_moderes = array(), $old
 				$destinataire .= ";". $value;
 			}
 
-			Email::Envois($destinataire, $sujet, $message, $repondre, '', '');
+		//	Email::Envois($destinataire, $sujet, $message, $repondre, '', '');  semble incomplet YN le 21/02/2020
 		}
 
 		$sujet7 = $vocab["subject_mail1"].$room_name." - ".$date_avis;

programming_language: PHP
filename: misc.inc.php
change_type: ModificationType.MODIFY
diff: @@ -2,7 +2,7 @@
 /**
  * misc.inc.php
  * fichier de variables diverses
- * Dernière modification : $Date: 2020-01-28 17:15$
+ * Dernière modification : $Date: 2020-03-13 13:15$
  * @author    JeromeB & Laurent Delineau & Yan Naessens
  * @copyright Copyright 2003-2020 Team DEVOME - JeromeB
  * @link      http://www.gnu.org/licenses/licenses.html
@@ -25,7 +25,7 @@ $grr_devel_url = "http://grr.devome.com/";
 $version_grr = "3.4.1";
 // Numéro de sous-version actuel (a, b, ...)
 // Utilisez cette variable pour des versions qui corrigent la la version finale sans toucher à la base.
-$sous_version_grr = "b"; // a, b, c, ...
+$sous_version_grr = "c"; // a, b, c, ...
 // Numéro de la release candidate (doit être strictement inférieure à 9). Laisser vide s'il s'agit de la version stable.
 $version_grr_RC = "";
 // Version repository (GitHub)

programming_language: Perl