Précédent   Forum des professionnels en informatique > PHP > Langage > Fichiers
Fichiers Forum d'entraide sur les fichiers avec PHP. Avant de poster -> FAQ fichiers et Sources fichiers
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
Vieux 17/11/2009, 14h44   #1
Nouveau Membre du Club
 
Avatar de langevert
 
Inscription : août 2007
Messages : 92
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 92
Points : 38
Points : 38
Par défaut Sécurité contre injection de code dans upload

Bonjour,

J'ai crée en PHP un système d'upload d'images.
Pour des raisons de sécurité, j'ai décidé de refuser toutes les images dont les 1ers octets (numéro magique) ne correspondent pas à une image jpeg ou gif.

Seulement cette protection ne suffit pas : En effet, un fichier peut débuter avec le numéro magique d'un gif (et sera donc accepté), puis peut être suivi de code malicieux comme du PHP...

Pour éviter ce problème, j'ai procédé comme cela:
- Les fichiers uploadés sont stockés en dehors du répertoire web (donc pas accessible directement)
- J'ai crée un fichier image.php?name=image_name , dont voici une version simplifiée:

Code :
1
2
3
4
5
6
7
8
 
$name = $_GET['name'];
$pic =  '/myFolder/'.$name;
/*Note: On teste le nom du fichier pour savoir si il existe, et pour protéger de tout parcours de répertoire (autoriser uniquement des fichiers existants qui sont dans un répertoire précis)  -- Pas précisé ici toutes les vérifications pour alléger l'exemple*/
 
header("Content-Type: image/gif");   //ou jpeg si jpeg
 
readfile($pic);
Puis donc après dans ma page:
Code :
1
2
 
<img src="image.php?name=image_18" alt="mon image"/>
Le problème est donc résolu.
J'aimerai ensuite créer des miniatures. J'aimerai savoir si le code suivant protége aussi contre une telle faille :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
//On récupere le nom du fichier à afficher (avec les memes protection que citées dans le code précédént)
$name = $_GET['name'];
$pic =  '/myFolder/'.$name;
 
header("Content-Type: image/gif");   //ou jpeg si jpeg
 
//On récupère les infos sur l'image
$info_img = @getimagesize($pic);
 
if(!$info_img )
{
    exit();
}
 
//Creation de la miniature
$img_out = imagecreatetruecolor(100, 100);
$img_in = imagecreatefromgif($pic);
imagecopyresampled($img_out, $img_in, 0, 0, 0, 0, imagesx($img_out), imagesy($img_out), imagesx($img_in), imagesy($img_in));
imagegif($img_out);

Autre petite question: De telles protection empecherait par exemple l'éxécution de code PHP. Mais est-ce pareil pour du code JS? (faille XSS). Si non, comment protéger?

Merci d'avance pour vos réponses.
langevert est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/11/2009, 11h17   #2
Membre éprouvé
 
Avatar de d-Rek
 
Développeur Web
Inscription : janvier 2007
Messages : 438
Détails du profil
Informations personnelles :
Localisation : France, Nord (Nord Pas de Calais)

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : janvier 2007
Messages : 438
Points : 400
Points : 400
Pour ne pas te poser de soucis après coup, il faut verrouiller ton système à l'upload. Quand tu reçois un fichier, vérifier plutôt le mime-type afin qu'il soit en accord avec l'extension.
Exemple, j'ai un fichier PHP, je le renomme en .gif, l'upload fonctionne mais si j'appelle l'URL du fichier gif, ton serveur renvoie une entête image/gif : l'image ne s'affiche pas, le code ne s'exécute pas.

On obtiens le Mime-type ainsi : $_FILES['mon_fichier']['type']
En gros :
Code php :
1
2
3
4
5
6
?php
$extensions_auth = array('jpg', 'jpeg', 'gif', 'png', 'bmp');
if(in_array(substr(strrchr(strtolower($_FILES['mon_fichier']['name']), '.'), 1), $extensions_auth) AND substr(strtolower($_FILES['mon_fichier']['type']), 0, 6)=='image/'){
	// mimeType & extension pour image alors ok on fait un move_uploaded_file vers un répertoire web accessible
}
?>
__________________
Mon blog
d-Rek est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2009, 10h24   #3
Nouveau Membre du Club
 
Avatar de langevert
 
Inscription : août 2007
Messages : 92
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 92
Points : 38
Points : 38
Merci pour votre réponse.
Par contre, par simple curiosité avez-vous la réponse aux questions?

Quand vous dites d'utiliser la variable $_FILES['mon_fichier']['type'], je ne trouve pas très sécurisé car cette variable n'est pas forcement correcte (facile à changer par le client)
langevert est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/12/2009, 00h24   #4
Membre du Club
 
Inscription : novembre 2006
Messages : 84
Détails du profil
Informations forums :
Inscription : novembre 2006
Messages : 84
Points : 63
Points : 63
Effectivement il ne faut absolument pas se fier au type MIME ($_FILES['mon_fichier']['type']) que l'on peut fausser vis a vis du vrai contenu du fichier !

Par contre j'ai trouvé un site pas mal qui se pose les mêmes problématiques de sécurité d'upload et download de fichiers en évitant les injections PHP.

A ce que j'en ai compris, l'idéal est de configurer Apache de la sorte :

Code :
1
2
# Forcer le téléchargement du fichier
        ForceType application/force-download
Ou tel que le fait Comment forcer le téléchargement d'un fichier ? ( Header, FilesMatch ) :

Code :
1
2
3
4
5
6
<IfModule mod_headers.c>
	<FilesMatch "\.(jpe?g)$">
		ForceType image/jpeg
		Header set Content-Disposition attachment
	</FilesMatch>
</IfModule>
sjachym est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +1. Il est actuellement 18h52.


 
 
 
 
Partenaires

Hébergement Web