CVE-2020-10562 (PHP, published 2020-03-13T21:15Z)
Description: value: An issue was discovered in DEVOME GRR before 3.4.1c. admin_edit_room.php mishandles file uploads.
Severity: MEDIUM (CVSS v3 base score: 7.2)
Weakness: CWE-434 \u2014 Unrestricted Upload of File with Dangerous Type
The product allows the upload or transfer of dangerous file types that are automatically processed within its environment.
Repository: https://github.com/JeromeDevome/GRR
Files changed:
CHANGELOG
admin/admin_edit_room.php
frmcontactlist.php
frmcontactrange.php
include/functions.inc.php
include/misc.inc.php
Commit message: sous-version 3.4.1c : mise à jour de sécurité


Vulnerable code:
 * Dernière modification : $Date: 2020-01-28 11:10$
		{
			$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))
		$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");
		// Definition des jours de la semaine e afficher sur les plannings et calendriers
 * Dernière modification : $Date: 2018-07-31 16:00$
 * @copyright Copyright 2003-2018 Team DEVOME - JeromeB
// 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");
 * Dernière modification : $Date: 2020-01-17 14:30$
    WHERE id = '".$id."' ";
			Email::Envois($destinataire, $sujet, $message, $repondre, '', '');
 * Dernière modification : $Date: 2020-01-28 17:15$
$sous_version_grr = "b"; // a, b, c, ...

Fixed code:
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
 * Dernière modification : $Date: 2020-03-13 12:30$
        {
            $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))
        // 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");
		// Definition des jours de la semaine à afficher sur les plannings et calendriers
 * Dernière modification : $Date: 2020-03-13 11:00$
 * @copyright Copyright 2003-2020 Team DEVOME - JeromeB
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");
 * Dernière modification : $Date: 2020-03-13 11:00$
if ($id != protect_data_sql($id))
    die('Donnée incorrecte');
    WHERE id = '".protect_data_sql($id)."' ";
		//	Email::Envois($destinataire, $sujet, $message, $repondre, '', '');  semble incomplet YN le 21/02/2020
 * Dernière modification : $Date: 2020-03-13 13:15$
$sous_version_grr = "c"; // a, b, c, ...