PHP téléchargement d'image de sécurité liste de contrôle
Je suis de la programmation d'un script d'upload d'images pour mon application. Sont les suivantes étapes de sécurité suffisamment pour en faire la demande à l'abri de l'script côté?
- Désactiver PHP en cours d'exécution à l'intérieur du dossier de téléchargement à l'aide .httaccess.
- Ne permettent pas de télécharger si le nom de fichier contient la chaîne "php".
- Autoriser uniquement les extensions sont: jpg,jpeg,gif et png.
- Permettre uniquement un type de fichier d'image.
- Interdire image avec deux type de fichier.
- Changer le nom de l'image.
- De télécharger vers un sous-répertoire ne répertoire racine.
C'est mon script:
$filename=$_FILES['my_files']['name'];
$filetype=$_FILES['my_files']['type'];
$filename = strtolower($filename);
$filetype = strtolower($filetype);
//check if contain php and kill it
$pos = strpos($filename,'php');
if(!($pos === false)) {
die('error');
}
//get the file ext
$file_ext = strrchr($filename, '.');
//check if its allowed or not
$whitelist = array(".jpg",".jpeg",".gif",".png");
if (!(in_array($file_ext, $whitelist))) {
die('not allowed extension,please upload images only');
}
//check upload type
$pos = strpos($filetype,'image');
if($pos === false) {
die('error 1');
}
$imageinfo = getimagesize($_FILES['my_files']['tmp_name']);
if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg'&& $imageinfo['mime'] != 'image/jpg'&& $imageinfo['mime'] != 'image/png') {
die('error 2');
}
//check double file type (image with comment)
if(substr_count($filetype, '/')>1){
die('error 3')
}
//upload to upload direcory
$uploaddir = 'upload/'.date("Y-m-d").'/' ;
if (file_exists($uploaddir)) {
} else {
mkdir( $uploaddir, 0777);
}
//change the image name
$uploadfile = $uploaddir . md5(basename($_FILES['my_files']['name'])).$file_ext;
if (move_uploaded_file($_FILES['my_files']['tmp_name'], $uploadfile)) {
echo "<img id=\"upload_id\" src=\"".$uploadfile."\"><br />";
} else {
echo "error";
}
Tout nouveaux conseils sont les bienvenus 🙂
- Je voudrais supprimer la règle suivante: Ne pas autoriser le transfert si le nom de fichier contient la chaîne "php". Il n'est pas nécessaire parce que vous êtes en renommant le fichier.
- Vous pouvez télécharger Sécuriser le transfert d'Image à partir de github. C'est le plus sûr script PHP vivant. Il prend en charge l'image de re-dimensionnement/croping trop.
- À partir d'un rapide coup d'œil à cette catégorie de la sécurité que je peux voir, c'est une extension de vérifier. S'il vous plaît, s'il vous PLAÎT dire qu'il n'est pas vrai!
- Ce n'est pas vrai. Dans quel sens? le
pathinfo(, PATHINFO_EXTENSION)
est une très bonne façon d'obtenir le plus précis extension de fichier, en fait il n'y a rien de plus fiable que cela. lire, où il est dit note - Si j'ai quitté la sécurité de mon serveur vers le bas à une extension de vérifier je ne serais pas capable de dormir la nuit est ce que je dis
- Eh bien, si vous n'êtes pas assez intelligent pour ne pas donner à vos dossiers d'autorisation pour l'exécution des fichiers, la je suis d'accord. Vous ne devriez pas dormir 🙂
- Je suis assez intelligent cependant, je ne suis pas concordants laissant un tel risque à une simple vérification qui peut laisser le code de l'exécutable sur votre serveur qui pourrait être un maillon très important dans une chaîne qui permet de fuite de choses comme les détails de compte, la plupart du monde réel hacks ne viennent pas d'une vulnérabilité, mais quelques utilisés conjointement. EDIT: je vois votre Suisse, bon 🙂
- Je ne suis pas Suisse :). Pourquoi ne pas télécharger les classes et essayez de votre mieux pour la battre? Je suis vraiment intéressé de savoir comment il peut être exploité. Je ne suis pas sûr à 100%, comme je suis en PHP débutant. Mais, je veux utiliser la classe dans des projets d'avenir donc, je voudrais savoir
- Juste assez 🙂 en fait, je suis actuellement à l'élaboration d'une sécurité de téléchargement d'images, de stockage, et de servir de classe en PHP, donc je suis très paranoïaque lors de la lecture de la façon dont toutes ces vérifications peuvent être contournées. Si vous utilisez le script, assurez-vous de stocker les images à côté de la racine du document et de les afficher à l'aide de PHP, encadrez quelque chose se passe
- Bien sûr, laissez-moi vérifier votre code lorsque vous avez terminé. J'ai besoin d'apprendre autant que possible. Je pense que mon script est sûr, mais il peut être très améliorée. Donc, j'ai besoin de le comparer avec les autres
- l'ofc & btw j'aime le Luc 3:11 licence 🙂
Vous devez vous connecter pour publier un commentaire.
Re-traiter l'image à l'aide de GD (ou Imagick) et enregistrer l'image traitée. Tous les autres sont juste des
funennuyeux pour les pirates.Edit: Et comme rr l'a souligné, l'utilisation
move_uploaded_file()
pour tout télécharger.Fin Edit: au fait, vous voulez être très restrictives au sujet de votre dossier de téléchargement. Ces lieux sont l'un des coins sombres où de nombreux exploits arriver. Ceci est valable pour n'importe quel type de télécharger et de tout langage de programmation/serveur. Vérifier https://www.owasp.org/index.php/Unrestricted_File_Upload
try { $image = new Imagick($_FILES['my_files']['tmp_name']); $image->writeImage($outFile); } catch (ImagickException) { //invalid image or something }
Pour les tests de sécurité des fichiers d'image, je pense, de 4 niveaux de titres. Ils doivent être:
($file_info = getimagesize($_FILES['image_file']; $file_mime = $file_info['mime'];)
Remarque: le Chargement de l'image entière serait lente.
XSS Avertissement
Un plus très important remarque. Ne servent pas/télécharger quoi que ce soit qui pourrait être interprété comme du HTML dans le navigateur.
Étant donné que les fichiers sont sur votre domaine, javascript contenues dans ce document HTML aurez accès à tous vos cookies, permettant à une sorte d'attaque XSS.
Scénario d'attaque:
L'attaquant upload de fichier HTML avec du code JS qui envoie tous les cookies de son serveur.
L'attaquant envoie le lien à vos utilisateurs via mail, MP, ou via une iframe sur son site ou tout autre site.
Plus sécurisée, la solution:
Faire du contenu téléchargé disponible uniquement sur le sous-domaine ou sur un autre domaine. De cette façon, les cookies ne sont pas accessibles. C'est aussi l'un des google des conseils de performances:
https://developers.google.com/speed/docs/best-practices/request#ServeFromCookielessDomain
Vous pouvez l'exécuter "is_uploaded_file" sur la variable $_FILES['my_files']['tmp_name'] ainsi. Voir http://php.net/manual/en/function.is-uploaded-file.php
Créer un nouveau .htaccess dans le télécharge dir et collez ce code:
Assurez-vous simplement de renommer les fichiers u téléchargement + oublier la vérification des types, matières, etc
Je vais le répéter quelque chose que j'ai posté en question connexe.
Vous pouvez détecter le type de contenu à l'aide de Fileinfo fonctions (mime_content_type() dans les versions précédentes de PHP).
Un extrait de formulaire PHP manuel sur les vieux type mime extension, qui est maintenant remplacé par Fileinfo:
getimagesize()
peut aussi faire un bon travail, mais la plupart des autres vérifications que vous effectuez sont des non-sens. Par exemple, pourquoi chaînephp
n'est pas autorisé dans le nom de fichier. Vous n'allez pas inclure le fichier image dans le script PHP, juste parce que son nom contientphp
chaîne, êtes-vous?Quand il s'agit de la re-création d'images, dans la plupart des cas, il permettra d'améliorer la sécurité... jusqu'à ce que la bibliothèque que vous utilisez n'est pas vulnérable.
Donc extension PHP qui convient le mieux pour sécuriser l'image de la re-création? J'ai vérifié CVE de détails site web. Je pense que l'applicables trio sont ces extensions:
De la comparaison, je pense que GD convient le mieux, parce qu'il a le plus petit nombre de questions de sécurité et ils sont assez vieux. Trois d'entre eux sont essentiels, mais ImagMagick et Gmagick ne pas faire mieux... ImageMagick semble être très bogué (au moins quand il s'agit de la sécurité), je choisis donc d'Gmagick que la deuxième option.
si la sécurité est très importante utilisation de la base de données pour enregistrer le nom de fichier et rebaptisé du nom de fichier et ici vous pouvez changer l'extension de fichier de quelque chose comme .myfile et de faire un fichier php pour envoyer des images avec les en-têtes . php peut être plus sûr, et vous pouvez l'utiliser dans la balise img, comme coup :
également vérifier l'extension de fichier avec EXIF avant de le télécharger.
La réponse la plus simple à autoriser les utilisateurs à télécharger des fichiers en toute sécurité en PHP est: Toujours enregistrer des fichiers à l'extérieur de la racine du document.
Par exemple: Si la racine du document est
/home/example/public_html
, enregistrer des fichiers à/home/example/uploaded
.Avec vos fichiers en toute sécurité hors de l'enceinte de l'être exécuté directement par votre serveur web, il ya un couple de façons dont vous pouvez toujours les rendre accessibles à vos visiteurs:
Toutefois, si vous allez avec les options 1 ou 3 sur cette liste et que vous avez un local file inclusion vulnerability dans votre application, votre formulaire de téléchargement de fichier peut encore être un vecteur d'attaque.
Le meilleur façon de garder votre site est sécurisé lorsque l'utilisateur de télécharger l'image est pour cela suit :
je pense que c'est le meilleur moyen ! trouver quel est votre avis ?
Pour un fichier image, vous pouvez également modifier les permissions du fichier après le changement de nom pour être sûr qu'il ne s'exécute jamais (rw-r--r--)
Je suis en utilisant php télécharger un script qui crée une nouvelle aléatoire de 4 octets pour chaque fichier téléchargé, puis XORs le contenu du fichier avec ces 4 octets (à répéter autant de fois que nécessaire), et enfin l'attache, les 4 octets dans le fichier avant de l'enregistrer.
Pour le téléchargement, les 4 octets doivent être coupés de nouveau le fichier, le contenu sera XORed avec eux à nouveau et le résultat est envoyé au client.
De cette façon, je peux être sûr que les fichiers que j'ai enregistrer sur le serveur ne sera pas exécutable ou ont un potentiel de sens que ce soit, pour n'importe quelle application. En Plus je n'ai pas besoin de base de données supplémentaire pour stocker les noms de fichiers dans.
Voici le code que j'utilise:
Upload:
Télécharger: