J'ai lu sur la sécurité du téléchargement de fichier PHP et quelques articles ont recommandé de renommer les fichiers. Par exemple, l'article Téléchargement de fichier non restreint dit: p>
Il est recommandé d'utiliser un algorithme pour déterminer les noms de fichiers. Pour exemple, un nom de fichier peut être un hachage MD5 du nom du fichier plus le Date de la journée. P> blockQuote>
Si un utilisateur télécharge un fichier nommé
recette de gâteau.doc code> existe-t-il vraiment une raison pour le renommer à
45706365b7d5b1f35 code>? P>
Si la réponse est oui, pour quelque raison que ce soit, alors comment gardez-vous une trace du nom du fichier et de l'extension d'origine? P>
3 Réponses :
Lorsque je télécharge des fichiers, j'utilise la fonction unique_id () de PHP pour le nom de fichier stocké sur le serveur (et je préserve l'extension de fichier car elle vous facilite la tâche lorsque je regarde tous les fichiers du répertoire de stockage via le système de fichiers local).
Je sauvegardez le fichier en dehors du système de fichiers Web (AKA Vous ne pouvez jamais naviguer directement dans les fichiers). p>
J'utilise toujours la fonction PHP's Move_Uploaded_File () pour enregistrer le fichier sur le serveur. P>
Je stocke le nom de fichier d'origine, le chemin / le nom de fichier où il est stocké et tout autre projet lié Informations dont vous pourriez avoir besoin sur qui l'a téléchargé, etc. dans une base de données. P>
Dans certaines de mes implémentations, je crée également un hachage du contenu du fichier et enregistrer cela dans la base de données aussi. Ensuite, avec d'autres fichiers téléchargés, consultez la base de données pour voir si j'en ai une copie de ce fichier exact déjà stocké. P>
Quelques exemples de code: p>
Le formulaire: forte > p> <?php
// Do all neccessary security checks etc to make sure the user is allowed to download the file, etc..
//
$file = '/path/to/your/storage/directory' . 'the_stored_filename';
$filesize = filesize($file);
header('Content-Description: File Transfer');
header("Content-type: application/forcedownload");
header("Content-disposition: attachment; filename=\"filename_to_display.example\"");
header("Content-Transfer-Encoding: Binary");
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header("Content-length: ".$filesize);
ob_clean();
flush();
readfile("$file");
exit;
à votre question principale, est-il une bonne pratique de renommer des fichiers, la réponse est un oui défini, surtout si vous créez une forme de référentiel de fichiers où les utilisateurs téléchargent des fichiers (et des noms de fichiers) de leur choix, pour plusieurs raisons: < ol>
recette de gâteau.doc code> n'est pas un nom de sécurité URL, et peut sur certains systèmes (côté serveur ou navigateur) / certaines situations, entraînent des incohérences lorsque le nom doit être un Urlencode code> d valeur d. li>
ol> comme pour stocker les informations, vous le feriez généralement dans une base de données, pas différent du besoin que vous avez déjà, car vous avez besoin d'un moyen de renvoyer au fichier (qui a téléchargé, quel nom est le nom. , occasionnellement où il est stocké, le temps de téléchargement, parfois la taille). Vous en ajoutez simplement à ce nom stocké le nom du fichier en plus du nom de l'utilisateur pour le fichier. P>
La recommandation OWASP n'est pas une mauvaise - Utilisation du nom de fichier et d'un horodatage (non date) serait surtout unique. Je prends une étape supplémentaire pour inclure le microtime avec l'horodatage, et souvent un autre peu d'informations unique, de sorte qu'un téléchargement en double d'un petit fichier ne pouvait pas se produire dans le même délai - je stocke également la date du téléchargement. qui est une assurance supplémentaire contre les affrontements MD5, qui a une probabilité plus élevée dans les systèmes qui stockent de nombreux fichiers et pendant des années. Il est incroyablement improbable que vous génériez deux md5, en utilisant le nom de fichier et Microtime, le même jour. Un exemple serait: p> xxx pré> mes 2 cents. P> p>
Il y a une bonne raison pour laquelle vous devez renommer le fichier téléchargé et c'est, Si deux téléchargements de même fichier, ou des fichiers avec le même nom, ce dernier fichier remplacera l'ancien fichier qui n'est pas favorable.
Vous pouvez utiliser des algues de hachage comme p> alors Vous pouvez enregistrer des détails sur le nom de fichier, le nom de fichier haché, le téléchargeur, la date, l'heure de garder une trace des fichiers p> p>
Habituellement, vous gardez une trace des fichiers en mettant le chemin et les informations sur le fichier dans une table de base de données. En ce qui concerne le renommage, je n'ai fait que renommer pour vous assurer que les noms de fichiers sont conviviaux. Par exemple,
recette de gâteau.doc code> a une place de l'espace, Linux n'aime pas vraiment les noms de fichiers espacés sur la ligne CommMand, donc si vous aviez besoin de faire fonctionner des fonctions de ligne de commande sur le fichier que vous devriez l'envelopper dans le bon citations si vous ne l'avez pas renommé.
Vous pouvez stocker le nom d'origine et l'extension dans la base de données avec le nouveau nom au moment du téléchargement.
Considérez un système mal conçu pour permettre à quelqu'un de télécharger des fichiers
.php code>. Si vous mettez les fichiers avec le nom fourni par l'utilisateur dans la racine de document de votre site, cet utilisateur peut désormais prendre complètement votre serveur, car ils peuvent télécharger et exécuter un code arbitraire sur votre serveur.