securité upload

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

08 mai 2006, 10:45

ta ta ta... tu peux le trouver tout seul celui là ! ;)
j'va commenter un peu plus :
if (! isset($erreur))  // Si la variable $erreur n'est pas définie, c'est que je n'ai pas eu d'erreur 
// la variable n'est définie avec un message d'erreur que si l'extension n'est pas autorisée ou si la taille du fichier est trop grande (cf. ton code)
// isSet($erreur) retourne vrai si la variable est définie
// (! isSet($erreur)) retourne donc vrai si elle n'est pas définie (puisqu'il y a un "!" devant)
// j'exécute donc le script suivant seulement si tout est ok jusque là
{
  // puisque tout est ok, je récupère le fichier uploadé dans le dossier qui va bien
  move_uploaded_file($nomTemporaire, $chemin.$nomFichier); 
}
Qu'est ce qui t'empêche de faire pareil un peu plus loin et de dire "je n'exécute la maj en base que si je n'ai pas eu d'erreur" ? :)

Eléphant du PHP | 297 Messages

08 mai 2006, 14:45

merci Ryle, en fait je comprends toujours avec tes explications, par contre, lorsqu'il s'agit de mettre ca en pratique et surtout en l'ecrivant :? :?
je viens de le faire et j'ai un parse error !
c'est que je bosse mes pages avec Dreamweaver...et j'ai un debut de code ou il y a deja un isset...
voici mon code avant la retouche
if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "form1")) {
  $insertSQL = sprintf("INSERT INTO bpays (id, pays, site, photo, chemin) VALUES (%s, %s, %s, %s, %s)",
                       GetSQLValueString($_POST['id'], "int"), 
                       GetSQLValueString($_POST['pays'], "text"), 
                       GetSQLValueString($_POST['site'], "text"), 
                       GetSQLValueString($nomFichier, "text"), // utilisation des variables nom 
                       GetSQLValueString($chemin, "text")); // et chemin 

  mysql_select_db($database_pays, $pays);
  $Result1 = mysql_query($insertSQL, $pays) or die(mysql_error());
et voici le debut avec ma modif qui entraine un parse error :cry:
if ((! isset($erreur)($_POST["MM_insert"])) && ($_POST["MM_insert"] == "form1")) {
  $insertSQL = sprintf("INSERT INTO bpays (id, pays, site, photo, chemin) VALUES (%s, %s, %s, %s, %s)",

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

08 mai 2006, 14:53

et qu'est ce qu'on met entre deux conditions dans un if pour les séparer et les rendre complémentaires ou indépendantes ? :) (et accessoirement éviter les parse error)

un opérateur... un opérateur lo... un opérateur logi... un opérateur logique ! bonne réponse !! c'est encore un militaire qui remporte une tringle à rideau ;)

Eléphant du PHP | 297 Messages

08 mai 2006, 15:18

tu veux dire "and", "or"...
si oui, entre quels if ??
et sais tu pourquoi je n'ai pas de messages d'erreurs qui s'affichent ?
merci pour la tringle a rideau...

Mammouth du PHP | 965 Messages

08 mai 2006, 15:21


Eléphant du PHP | 297 Messages

08 mai 2006, 16:28

j'ai simplifié un peu mon code au niveau de la partie verif en haut.
j'ai bien un message d'erreur si le format n'est pas bon, ou la taille...
par contre il execute tout de meme l'upload et la mise a jour de la base ! :cry:
comprends pas car j'ai un break non !!?
<?php
// je remonte la déclaration avant la récup du fichier 
$nomFichier = ""; // déclaration des variables 
$chemin = ""; 

//Script Upload
//on vérifies que le champ est bien rempli:
if(!empty($_FILES["photo"]["name"]))
$nomFichier    = $_FILES["photo"]["name"] ;  	//nom du fichier choisi:
$nomTemporaire = $_FILES["photo"]["tmp_name"] ;  	//nom temporaire sur le serveur:
$typeFichier   = $_FILES["photo"]["type"] ;   	//type du fichier choisi:
$poidsFichier  = $_FILES["photo"]["size"] ;   	//poids en octets du fichier choisit:
$codeErreur    = $_FILES["photo"]["error"] ;   	//code de l'erreur si jamais il y en a une:

// Tableau array des différents types accepté 
$allowed_types = array('bmp', 'gif', 'jpeg', 'jpg');

// Taille maximum 
$MAX_FILE_SIZE = 150000; 

//chemin qui mène au dossier qui va contenir les fichiers upload:
$chemin = "./images/" ;

 // vérifications
// Diverses test afin de savoir si : 
// Le format de fichier correspond  
if(!in_array($typeFichier, $allowed_types)){$error = 1;} 
 
// La taille du fichier n'est pas dépassée 
if($poidsFichier > $MAX_FILE_SIZE){$error = 2;} 
 
// Le fichier n'existe pas déjà 
if(file_exists($folder."m_".$nomFichier)){$error = 3;} 

//l'upload ! 
if (move_uploaded_file($nomTemporaire, $chemin.$nomFichier))  
 
// Switch gestion des erreurs 
switch($error){ 
case'0': 
echo("Fichier correctement envoyé." ); 
break; 
case'1': 
echo("Format de fichier incorrect." ); 
break; 
case'2': 
echo("Fichier trop volumineux." ); 
break; 
case'3': 
echo("Fichier déjà existant." ); 
break; 
} 

//debut script dream mise a jour table
function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "") 
{
  $theValue = (!get_magic_quotes_gpc()) ? addslashes($theValue) : $theValue;

  switch ($theType) {
    case "text":
      $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
      break;    
    case "long":
    case "int":
      $theValue = ($theValue != "") ? intval($theValue) : "NULL";
      break;
    case "double":
      $theValue = ($theValue != "") ? "'" . doubleval($theValue) . "'" : "NULL";
      break;
    case "date":
      $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
      break;
    case "defined":
      $theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
      break;
  }
  return $theValue;
}

$editFormAction = $_SERVER['PHP_SELF'];
if (isset($_SERVER['QUERY_STRING'])) {
  $editFormAction .= "?" . htmlentities($_SERVER['QUERY_STRING']);
}

if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "form1")) {
  $insertSQL = sprintf("INSERT INTO bpays (id, pays, site, photo, chemin) VALUES (%s, %s, %s, %s, %s)",
                       GetSQLValueString($_POST['id'], "int"), 
                       GetSQLValueString($_POST['pays'], "text"), 
                       GetSQLValueString($_POST['site'], "text"), 
                       GetSQLValueString($nomFichier, "text"), // utilisation des variables nom 
                       GetSQLValueString($chemin, "text")); // et chemin 

  mysql_select_db($database_pays, $pays);
  $Result1 = mysql_query($insertSQL, $pays) or die(mysql_error());

  $insertGoTo = "indexexemple.htm";
  if (isset($_SERVER['QUERY_STRING'])) {
    $insertGoTo .= (strpos($insertGoTo, '?')) ? "&" : "?";
    $insertGoTo .= $_SERVER['QUERY_STRING'];
  }
  header(sprintf("Location: %s", $insertGoTo));
}
?>

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

08 mai 2006, 20:57

Dans un switch, le break ne sert qu'à sortir sans exécuter l'instruction du case suivant :
switch ($var) {
  case 1 :
    echo "cas numéro 1";
    break;
  case 2 : 
    echo "cas numéro 2";
  case 3 :
    echo "cas numéro 3";
}

// si $var est égal à 1 ceci affiche :
cas numéro 1
// si $var est égal à 2 ceci affiche :
cas numéro 2
cas numéro 3
// si $var est égal à 3 ceci affiche :
cas numéro 3
Ainsi dans ton script, il affiche bien un message d'erreur, mais continue d'exécuter le script sans se soucier de savoir s'il y en a eu une ou pas vu que tu n'as plus de test autour du move_uploaded_file() et pas encore sur le insert...
if( /* si je n'ai pas d'erreur */) {
  // je déplace le fichier
}

if( /* si je n'ai pas d'erreur */) {
  // je joue le insert
}

dans ton script précédent c'était effectivement un && qui te manquait entre les deux premières conditions.

Eléphant du PHP | 297 Messages

08 mai 2006, 21:19

Merci Ryle,
tu ne pourrais m'en dire un peu plus stp ?
il me semble que cette deuxieme facon d'ecrire le script me semble plus simple !?
par contre elle ne fonctionne pas a 100% :cry:
ca fait tellement longtemps que je rame et me prends la tete sur ces tests... :(

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

08 mai 2006, 23:15

bof... ca m'a pas l'air spécialement plus simple.. y a un switch pour gérer les msg d'erreurs au lieu de le faire directement dans les if, et ca change rien aux tests à ajouter... mais le principal c'est qu'il soit suffisament clair pour toi :)
// Le fichier n'existe pas déjà 
if(file_exists($folder."m_".$nomFichier)){$error = 3;} 
Je ne sais pas ce que c'est que ce $folder et "m_", mais m'est avis que ca a peu de chance de fonctionner tel quel...

Pis pour les tests à ajouter, toujours ce !isSet($error) :
//l'upload ! 
if(!isSet($error)) {
  move_uploaded_file($nomTemporaire, $chemin.$nomFichier);
}
if (isset($_POST["MM_insert"]) && $_POST["MM_insert"] == "form1" && !isSet($error) ) { 
  $insertSQL = ...

Eléphant du PHP | 297 Messages

09 mai 2006, 05:01

ben, je suis revenu a mon premier code, que j'ai rereremodifier en suivant des conseils...(car le dernier m'affichait un message d'erreur fichier d'entrée !!)
maintenant plus de message d'erreur, mais un format fichier autre que ceux mentionnés passe, et aussi superieur au poids maxi :?
j'ai recherché d'autres exemples similaires, mais je ne vois pas mon erreur !!
bon je te repasse mon code...si tu veux encore m'aider...

<?php
// je remonte la déclaration avant la récup du fichier 
$nomFichier = ""; // déclaration des variables 
$chemin = ""; 

//Script Upload 
//on vérifies que le champ est bien rempli: 
$nomFichier    = $_FILES["photo"]["name"] ;      //nom du fichier choisi: 
$nomTemporaire = $_FILES["photo"]["tmp_name"] ;      //nom temporaire sur le serveur: 
$typeFichier   = $_FILES["photo"]["type"] ;       //type du fichier choisi: 
$poidsFichier  = $_FILES["photo"]["size"] ;       //poids en octets du fichier choisit: 
$codeErreur    = $_FILES["photo"]["error"] ;       //code de l'erreur si jamais il y en a une: 

unset($erreur); 
$extensions_ok = array('png', 'gif', 'jpg', 'jpeg'); 
$taille_max = 100000; 

//chemin qui mène au dossier qui va contenir les fichiers upload: 
$chemin = "./images/" ; 

// vérifications 
   if( !in_array( substr(strrchr($_FILES['photo']['name'], '.'), 1), $extensions_ok ) ) 
    { 
$erreur = 'Veuillez sélectionner un fichier de type png, gif ou jpg !'; 
    } 
    elseif( file_exists($_FILES['photo']['tmp_name']) 
    and filesize($_FILES['photo']['tmp_name']) > $taille_max) 
    { 
$erreur = 'Votre fichier doit faire moins de 100Ko !'; 
    } 


//l'upload ! 
if(!isset($error)) { 
  move_uploaded_file($nomTemporaire, $chemin.$nomFichier); 
} 
 
//debut script dream mise a jour table
function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "") 
{
  $theValue = (!get_magic_quotes_gpc()) ? addslashes($theValue) : $theValue;

  switch ($theType) {
    case "text":
      $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
      break;    
    case "long":
    case "int":
      $theValue = ($theValue != "") ? intval($theValue) : "NULL";
      break;
    case "double":
      $theValue = ($theValue != "") ? "'" . doubleval($theValue) . "'" : "NULL";
      break;
    case "date":
      $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
      break;
    case "defined":
      $theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
      break;
  }
  return $theValue;
}

$editFormAction = $_SERVER['PHP_SELF'];
if (isset($_SERVER['QUERY_STRING'])) {
  $editFormAction .= "?" . htmlentities($_SERVER['QUERY_STRING']);
}

if (! isset($erreur) && isset($_POST["MM_insert"]) && ($_POST["MM_insert"] == "form1")) { 
  $insertSQL = sprintf("INSERT INTO bpays (id, pays, site, photo, chemin) VALUES (%s, %s, %s, %s, %s)", 
                       GetSQLValueString($_POST['id'], "int"), 
                       GetSQLValueString($_POST['pays'], "text"), 
                       GetSQLValueString($_POST['site'], "text"), 
                       GetSQLValueString($nomFichier, "text"), // utilisation des variables nom 
                       GetSQLValueString($chemin, "text")); // et chemin 

  mysql_select_db($database_pays, $pays);
  $Result1 = mysql_query($insertSQL, $pays) or die(mysql_error());

  $insertGoTo = "indexexemple.htm";
  if (isset($_SERVER['QUERY_STRING'])) {
    $insertGoTo .= (strpos($insertGoTo, '?')) ? "&" : "?";
    $insertGoTo .= $_SERVER['QUERY_STRING'];
  }
  header(sprintf("Location: %s", $insertGoTo));
}
?>

Eléphant du PHP | 288 Messages

09 mai 2006, 09:28

Et si tu faisais les tests sur la bonne variable. Tu initialise $erreur
$erreur = 'Votre fichier doit faire moins de 100Ko !'; 
Et tu test $error ça peut pas marche
if(!isset($error)) 
Change pour
 if(!isset($erreur))
Bonne chance

Eléphant du PHP | 297 Messages

09 mai 2006, 15:28

merci Damaskinos,
ca fonctionne mieux :)
les fichiers autres que ceux mentionnés ne passent plus, ainsi que les fichiers volumineux,
par contre dans ce cas , il ne m'affiche pas le message d'erreur, et va direct a ma page d'accueil(qui est mentionnée en fin de code)
$insertGoTo = "indexexemple.htm";
voici de nouveau mon script :?
<?php
// je remonte la déclaration avant la récup du fichier 
$nomFichier = ""; // déclaration des variables 
$chemin = ""; 

//Script Upload 
//on vérifies que le champ est bien rempli: 
if(!empty($_FILES["photo"]["name"]))   { 
$nomFichier    = $_FILES["photo"]["name"] ;      //nom du fichier choisi: 
$nomTemporaire = $_FILES["photo"]["tmp_name"] ;      //nom temporaire sur le serveur: 
$typeFichier   = $_FILES["photo"]["type"] ;       //type du fichier choisi: 
$poidsFichier  = $_FILES["photo"]["size"] ;       //poids en octets du fichier choisit: 
$codeErreur    = $_FILES["photo"]["error"] ;       //code de l'erreur si jamais il y en a une: 

unset($erreur); 
$extensions_ok = array('png', 'gif', 'jpg', 'jpeg'); 
$taille_max = 100000; 

//chemin qui mène au dossier qui va contenir les fichiers upload: 
$chemin = "./images/" ; 

// vérifications 
   if( !in_array( substr(strrchr($_FILES['photo']['name'], '.'), 1), $extensions_ok ) ) 
    { 
$erreur = 'Veuillez sélectionner un fichier de type png, gif ou jpg !'; 
    } 
    elseif( file_exists($_FILES['photo']['tmp_name']) 
    and filesize($_FILES['photo']['tmp_name']) > $taille_max) 
    { 
$erreur = 'Votre fichier doit faire moins de 100Ko !'; 
    } 


//l'upload ! 
if(!isset($erreur)) { 
  move_uploaded_file($nomTemporaire, $chemin.$nomFichier); 
} 
 }
//debut script dream mise a jour table
function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "") 
{
  $theValue = (!get_magic_quotes_gpc()) ? addslashes($theValue) : $theValue;

  switch ($theType) {
    case "text":
      $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
      break;    
    case "long":
    case "int":
      $theValue = ($theValue != "") ? intval($theValue) : "NULL";
      break;
    case "double":
      $theValue = ($theValue != "") ? "'" . doubleval($theValue) . "'" : "NULL";
      break;
    case "date":
      $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
      break;
    case "defined":
      $theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
      break;
  }
  return $theValue;
}

$editFormAction = $_SERVER['PHP_SELF'];
if (isset($_SERVER['QUERY_STRING'])) {
  $editFormAction .= "?" . htmlentities($_SERVER['QUERY_STRING']);
}

if (! isset($erreur) && isset($_POST["MM_insert"]) && ($_POST["MM_insert"] == "form1")) { 
  $insertSQL = sprintf("INSERT INTO bpays (id, pays, site, photo, chemin) VALUES (%s, %s, %s, %s, %s)", 
                       GetSQLValueString($_POST['id'], "int"), 
                       GetSQLValueString($_POST['pays'], "text"), 
                       GetSQLValueString($_POST['site'], "text"), 
                       GetSQLValueString($nomFichier, "text"), // utilisation des variables nom 
                       GetSQLValueString($chemin, "text")); // et chemin 

  mysql_select_db($database_pays, $pays);
  $Result1 = mysql_query($insertSQL, $pays) or die(mysql_error());

  $insertGoTo = "indexexemple.htm";
  if (isset($_SERVER['QUERY_STRING'])) {
    $insertGoTo .= (strpos($insertGoTo, '?')) ? "&" : "?";
    $insertGoTo .= $_SERVER['QUERY_STRING'];
  }
  header(sprintf("Location: %s", $insertGoTo));
}
?>

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

09 mai 2006, 16:09

Ce qui semble assez logique, vu qu'à aucun moment tu ne lui demandes d'afficher le message contenu dans $erreur :)

C'est bien beau de tester si on a pas eu d'erreur et de mettre des if(!isSet($erreur)) de partout pour pas exécuter ce qui ne doit pas l'être mais... faut aussi penser à glisser au moins un if(isSet($erreur)) quelque part et gérer le cas ou ca n'a pas marché ;)

Cela dit, ca me parait bizare qu'il puisse t'exécuter le header(sprintf("Location: %s", $insertGoTo)); alors que celui-ci est inclus dans un if avec la condition !isset($erreur) .... je pense qu'arrivé en bas, il t'affiche juste la page sans rediriger quoi que ce soit :)

Eléphant du PHP | 297 Messages

09 mai 2006, 19:59

salut Ryle,
ben j'en posé deux if(isSet($erreur))
//l'upload ! 
if(!isset($erreur)) { 
  move_uploaded_file($nomTemporaire, $chemin.$nomFichier); 
} 
et
if (! isset($erreur) && isset($_POST["MM_insert"]) && ($_POST["MM_insert"] == "form1")) { 
  $insertSQL = sprintf("INSERT INTO bpays (id, pays, site, photo, chemin) VALUES (%s, %s, %s, %s, %s)", 
:) il m'en manque ?

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

10 mai 2006, 10:53

ta ta ta.. ceci relève d'un manque flagrant d'observation, et de la négligeance d'un élément capital en informatique qui est le point d'exclamation "!" :)

Il revient à dire NON ou PAS ou "le contraire de".
Donc si VRAI = VRAI, !VRAI = FAUX

(isSet($erreur)) = est ce que la variable $erreur est définie
(!isset($erreur)) = est ce que la variable $erreur est PAS définie
(ouais je sais, c'est pas français, mais ça a le mérite d'être clair ;))

Tu testes effectivement deux fois si la variable n'est pas définie, mais à aucun moment tu ne dis quoi faire si elle l'est... Tu pourrais faire quelque chose comme :
if (isSet($erreur)) { // en cas d'erreur
  echo $erreur; // affiche le message contenu dans $erreur
}
ou rediriger, ou mettre un message d'insulte à l'égard de l'utilisateur qui n'est pas foutu d'uploader un fichier convenablement, ou tu lui envoi un virus, tu lui formates son disque, tu fais sonner son téléphone pendant qu'il est sous la douche, et tu lui colles des p'tits crabes blancs dans ses moules ! ;)