[PHP] Upload et sécurité : renommer le fichier suffit ?

Upload et sécurité : renommer le fichier suffit ? [PHP] - PHP - Programmation

Marsh Posté le 20-07-2006 à 20:54:22    

Bonjour,
 
On lit beaucoup de choses plus ou moins vraies sur Internet sur comment sécuriser un script d'upload PHP.
 
Dans mon cas je souhaite faire un upload d'image jpeg dans un répertoire dans lequel je pourrais les afficher pour validation avant de les mettre en ligne.
- Est-ce que le fait de renommer le fichier sous un format $nom=numero_aleatoire().".jpg" suffit à éviter qu'un utilisateur malintentionné n'exécute du code malicieux sur le site ? Si oui, avez-vous des exemples et des solutions de contournement ?
- En particulier, je souhaite éviter que l'utilisateur parvienne à utiliser le formulaire pour écraser un fichier du site en bidouillant les variables. Y a-t-il des risques si on renomme le fichier de destination sous un format $nom=numero_aleatoire().".jpg" ?
 
Bonne soirée !

Reply

Marsh Posté le 20-07-2006 à 20:54:22   

Reply

Marsh Posté le 21-07-2006 à 03:30:10    

avant tout, n'autorise que les extentions dont tu as besoin (ici .jpg, .jpeg, .gif, .png)
de cette manière personne ne pourra par exemple lancer des scripts php sur ton serveur.
 
ensuite, met un .htacess dans ton répertoire où les fichiers sont up. met y "deny from all" (sans les guillemets).
 
après il ne te reste plus qu'à générer un numéro assez aléatoire pour que la probabilité soit assez faible qu'un numéro ne sorte pas 2 fois pendant un cours laps de tps (à la manière de PHPSESSID)

Reply

Marsh Posté le 21-07-2006 à 03:46:26    

twisted a écrit :

avant tout, n'autorise que les extentions dont tu as besoin (ici .jpg, .jpeg, .gif, .png)
de cette manière personne ne pourra par exemple lancer des scripts php sur ton serveur.


 [:theepsilon] C'est pas plus simple de vérifier que c'est une image ?
http://uk2.php.net/manual/fr/funct [...] getype.php
 


---------------
my flick r - Just Tab it !
Reply

Marsh Posté le 21-07-2006 à 07:42:07    

zapan666 a écrit :

[:theepsilon] C'est pas plus simple de vérifier que c'est une image ?
http://uk2.php.net/manual/fr/funct [...] getype.php


 
l'un n'exclut pas l'autre, que se passe t'il si j'upload un fichier .php qui commence comme un certain format d'image (certains sont surement assez laxistes pour le faire) pour tromper exif_imagetype. mais qui, s'il n'est pas renommé peut s'exécuter validement comme un script php ? (ca c'est pas trop dur, tout ce qui précède le <? sera ignoré par php ... a partir de la, c'est la fête :D)


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 21-07-2006 à 07:43:52    

quand je parlais de vérifier l'extension, il y a plusieurs façon.
 
par exemple en utilisant $_FILES["file"]["type"] ou bien cette fonction exif_imagetype().
à toi de voir ;-)

Reply

Marsh Posté le 21-07-2006 à 08:18:32    

si je renomme systématiquement le fichier en .jpg, est-il quand même possible que d'une manière ou d'une autre il permette d'exécuter du code ???

Reply

Marsh Posté le 21-07-2006 à 08:27:44    

pas du coté du serveur, mais du coté du client oui.
 
IE outrepasse le type mime et l'extention et fait de la détection "intelligente" du format du fichier, si quelqu'un envoie un .swf et que tu ne fais pas plus de vérifications que l'extention, les gens sous IE que l'on incitera à voir le fichier, même nommé .jpg vont lancer le fichier comme un .swf, avec toutes les capacités et autorisations qu'un fichier flash peut avoir.


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 21-07-2006 à 08:51:56    

Oui mais si tu verifies que le mime est bien un jPG à l'upload, il n'y aura pas de soucis :heink: .. C'est d'ailleurs sur une faille comme ça que c'était basé le type qui avait outrepassé les protections de ce forum, en se metant par la suite super-admin :D


Message édité par esox_ch le 21-07-2006 à 08:52:08

---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 21-07-2006 à 09:02:59    

c'est bien ce que je dis, il faut toujours vérifier les deux ;) L'un sans l'autre et tu finis par ouvrir une faille quelque part.


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 21-07-2006 à 09:11:17    

twisted a écrit :

quand je parlais de vérifier l'extension, il y a plusieurs façon.
 
par exemple en utilisant $_FILES["file"]["type"] ou bien cette fonction exif_imagetype().
à toi de voir ;-)


$_FILES["file"]["type"]  n'est pas sécurisé, il est possible de le 'feinter'
exif_imagetype() est securisé : si il te dit que l'image est un jpg, c'est que c'en est un  
 
et de ce fait , une image n'est pas executable ( sauf exploitation, d'un bug du navigateur, mais bon )

Reply

Marsh Posté le 21-07-2006 à 09:11:17   

Reply

Marsh Posté le 21-07-2006 à 09:42:23    

flo850 a écrit :

$_FILES["file"]["type"]  n'est pas sécurisé, il est possible de le 'feinter'
exif_imagetype() est securisé : si il te dit que l'image est un jpg, c'est que c'en est un  
 
et de ce fait , une image n'est pas executable ( sauf exploitation, d'un bug du navigateur, mais bon )


Tu veux dire du serveur hein? Parceque si tu fais le controle en PHP, le navigateur y est pas pour grand chose [:pingouino]


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 21-07-2006 à 09:45:05    

il y a des bugs dans une librairie de gestion d'image. Ces bugs permettent, avec une images bien construite de poser des pb au client  
 
il n'y a pas , a ma connaissance, de moyen  pour vérifier que l'image uploadée n'est pas  "piégée" , mais dans tous les cas, une image testée avec exif, et qui n'est pas de type flash , ne peux pas etre "executée" cotée serveur et ene peux donc pas mettre en danger le serveur

Reply

Marsh Posté le 21-07-2006 à 10:28:59    

Perso, je fais un truc simple pour gérer mes upload d'images :
- upload dans un répertoire en dehors du site (ou un répertoire qui fait deny all, en GET comme en POST, quel que soit l'utilisateur)
- avant d'enregistrer, je passe par une lib qui permet de manipuler des images, de façon à planter si le fichier n'est pas une image. je me sers de cette lib pour ensuite enregistrer l'image dans un format que je préfère (comme ça, je permet d'uploader un *.wmf ou un *.tiff de 100 Mo, et j'en fait un JPG de 40 Ko)
- pour relire, je passe par une page dédiée qui renvoie le type-mime détecté dans le fichier, et qui envoit le contenu du fichier sous forme binaire
 
un peu comme dans la gallerie d'images sur mon site (cf. signature) : les images ne sont pas accessibles directement, mais on passe par un fichier "image.asp". Ca me permet notamment de définir si l'utilisateur à le droit ou non de voir l'image, ou simplement, sans code particulier, de servir la miniature ou l'image au format original.
 
par contre, je ne renomme pas les images sur le disque : c'est chiant pour les retrouver après, et de toute façon, vu les précautions déjà prises, y'a aucun risque.
 
-- nan, pas ma signature en fait... http://www.manga-torii.com/default [...] ies&id=194


Message édité par Arjuna le 21-07-2006 à 10:29:52
Reply

Marsh Posté le 21-07-2006 à 10:35:16    

petite question a arjuna en passant : les miniatures, tu les calcules lors de l'upload , ou lors de la demand de la page ?  
 
perso , j'ai fait le choix de le faire lors de l'upload ( meme si c'est un peu long quand la perosnne envoi un zip d'image )

Message cité 1 fois
Message édité par flo850 le 21-07-2006 à 10:35:30
Reply

Marsh Posté le 21-07-2006 à 10:38:30    

dans cette version, parceque j'ai pas vraiment les libs nécessaires, je le fait à l'upload.
 
par contre, si je devais le refaire, je pense que je le ferais au moment de servir. non pas pour des problèmes de performance, puisque c'est plus lent, mais surtout pour personnaliser la taille de la miniature comme on veut, et pour chaque utilisateur.

Message cité 1 fois
Message édité par Arjuna le 21-07-2006 à 10:43:09
Reply

Marsh Posté le 21-07-2006 à 10:59:43    

flo850 a écrit :

petite question a arjuna en passant : les miniatures, tu les calcules lors de l'upload , ou lors de la demand de la page ?  
 
perso , j'ai fait le choix de le faire lors de l'upload ( meme si c'est un peu long quand la perosnne envoi un zip d'image )


 
En cas de gros paquets d'images, tu peut ptêtre faire du progressif non ? Tu rends la main dessuite/rapidement et en arrière plan tu fait avancer le boulot, t'avertit l'utilisateur au fur et a mesure des images disponibles (ou il s'avertit tout seul en faisant des F5 :D)
 

Arjuna a écrit :

dans cette version, parceque j'ai pas vraiment les libs nécessaires, je le fait à l'upload.
 
par contre, si je devais le refaire, je pense que je le ferais au moment de servir. non pas pour des problèmes de performance, puisque c'est plus lent, mais surtout pour personnaliser la taille de la miniature comme on veut, et pour chaque utilisateur.


 
Si tu combine à un cache tu peut avoir les 2, s'il a l'image en cache pour les réglages choisis tu l'utilise, sinon tu la crée et tu la met dans le cache. (avec evidement un ptit prunage occasionnel pour pas laisser trainer des vieilleries que personne utilise)


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 21-07-2006 à 11:14:56    

il y a assez peu d'upload sur le site ( en gros 5 photographes pour 800 utilisateurs ) , donc j'ai pas trop enve de me prendre la tête avec ça
sachant qu'en plus , la structure du site fait que ca va etre assez compliquer a gérer ( la page de traitement est une page temporaire, apres il y a des redirections )

Reply

Marsh Posté le 21-07-2006 à 11:20:57    

0x90 a écrit :

Si tu combine à un cache tu peut avoir les 2, s'il a l'image en cache pour les réglages choisis tu l'utilise, sinon tu la crée et tu la met dans le cache. (avec evidement un ptit prunage occasionnel pour pas laisser trainer des vieilleries que personne utilise)


 
yes, y'avais un exemple de webservice en .NET qui marchait comme ça :
 
tu tapais une URL, et il allait chercher le site, et t'en rapportait une miniature.
si la miniature avait déjà été générée moins de 24 heures avant, il te la resservait direct.
 
c'est une solution aussi, mais perso, j'aime pas trop les caches, surtout pour une gallerie de cette taille (si un goret vient et charge toutes les images, je fais avoir des milliers de fichiers en cache, c'est pas top :))

Reply

Marsh Posté le 21-07-2006 à 12:11:25    

justement non, un cache à des limites, régulièrement tu vérifie son état, si y'a plus de X images ou Mo, tu supprime les Y plus anciennes ou moins vues.


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 21-07-2006 à 15:32:48    

0x90 a écrit :

justement non, un cache à des limites, régulièrement tu vérifie son état, si y'a plus de X images ou Mo, tu supprime les Y plus anciennes ou moins vues.


justement, pour une gallerie d'images, où typiquement, chaque personne va en voir beaucoup et une seule fois, le cache n'a pas d'utilité, puisque je vais perdre plus de temps à le gérer qu'à m'en servir : la proba que x personnes de suite regardent les n mêmes images est d'autant plus grande si :
- x est petit (donc charge faible, donc pas d'utilité de mettre en cache)
- n est petit (donc charge faible, donc pas d'utilité de mettre en cache)
 
hors sur une gallerie, typiquement, x est TRES grand, et n relativement grand aussi.
à partir de là, c'est pas jouable.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed