11
votes

Capacités de téléchargement d'images d'utilisateur sécurisées en PHP

Je suis implémentant un outil de téléchargement d'image basé sur l'utilisateur pour mon site Web. Le système devrait permettre à tous les utilisateurs de télécharger uniquement des fichiers JPEG et PNG. Je suis bien sûr inquiet pour la sécurité et je me demande donc de la façon dont les nombreuses personnes plus intelligentes que moi ressentent des contrôles suivants pour permettre les téléchargements:

1) Premier liste blanche Les extensions de fichiers admissibles dans PHP à autoriser uniquement PNG , PNG, JPG, JPG et JPEG. Récupérez l'extension du fichier de l'utilisateur via une fonction telle que: xxx

ceci devrait aider à interdire à l'utilisateur de télécharger quelque chose de malicieux comme .png.php. Si cela passe, passez à l'étape 2.

2) Exécutez la fonction PHP getImageize () sur le fichier TMP. Via quelque chose comme: xxx

si cela ne renvoie pas faux, procédez.

3 3) Assurez-vous qu'un fichier .htaccess est placé dans le répertoire de téléchargements de sorte que Tous les fichiers de ce répertoire ne peuvent pas analyser les fichiers PHP: xxx

4) renommer le fichier de l'utilisateur à quelque chose de prédéterminé. C.-à-d. xxx

Cela aidera également à prévenir l'injection SQL car le nom de fichier sera la seule variable déterminée par l'utilisateur dans toutes les requêtes utilisées.

Si j'effectue le ci-dessus, quelle vulnérable pour attaque suis-je toujours? Avant d'accepter un fichier, j'espère avoir 1) uniquement autorisé JPGS et PNGS, 2) Vérifié que PHP dit qu'il s'agit d'une image valide, 3) désactivée le répertoire des images d'exécution des fichiers .php et 4) renommé le fichier utilisateurs à quelque chose unique.

merci,


1 commentaires

Pourriez-vous utiliser Strip_Tags sur un fichier image pour supprimer les étiquettes PHP?


4 Réponses :


24
votes

En ce qui concerne les noms de fichiers, des noms aléatoires sont vraiment une bonne idée et enlèvent beaucoup de maux de tête.

Si vous souhaitez faire totalement sûr que le contenu est propre, envisagez d'utiliser GD ou ImageMagick pour copier l'image entrante 1: 1 dans une nouvelle, vide.

qui diminuera légèrement la qualité de l'image, car le contenu est compressé deux fois, mais il supprimera toutes les informations EXIF ​​présentes dans l'image d'origine. Les utilisateurs ne sont souvent même pas conscients de la quantité d'informations dans la section de métadonnées des fichiers JPG! Info de la caméra, position, horaires, logiciels utilisés ... C'est une bonne politique pour les sites qui hébergent des images pour supprimer cette information pour l'utilisateur.

En outre, la copie de l'image se débarrassera probablement de la plupart des exploits qui utilisent des données d'image défectueuses pour provoquer des débordements dans le logiciel de la visionneuse et injecter du code malveillant. De telles images manipulées seront probablement simplement illusoires pour GD.


5 commentaires

Très bonne réponse. Je vais simplement ajouter cela en tant que défense supplémentaire, servez les images d'un domaine à deux pas que le domaine où vous définissez des cookies. De cette façon, même l'image a une manière d'une manière ou d'une autre avec un code secondaire du client exécutable, la même politique d'origine du navigateur empêchera beaucoup de mal.


@SRI Great Idée, n'en avez pas pensé à cela!


@SRIPATHIKRISHNAN Comment configurer un domaine de jeter un domaine pour les images .. Nany Référence..Pour votre réponse


@SID - Achetez un autre domaine et servez des images de ce domaine. Par exemple, Google sert le contenu de l'utilisateur auprès du domaine GoogleRerContent.com.


@SRIPATHIKRISHNAN Merci ..Commez-vous que je m'assurerai que le domaine est la cookieless et lorsque vous téléchargez des photos, devrai-je enregistrer des images dans ce domaine?



1
votes

Tous les chèques semblent bien, numéro 3 en particulier. Si la performance n'est pas un problème ou que vous le faites en arrière-plan, vous pouvez essayer d'accéder à l'image à l'aide de GD et de voir s'il s'agit d'une image et non seulement d'une bouquet de merde que quelqu'un essaie de remplir votre serveur. < / p>


0 commentaires

4
votes

Concernant votre numéro 2), vous ne voulez pas simplement vérifier false code>. GetImagesize retournera également le type MIME de l'image. Ceci est de loin un moyen plus sûr de vérifier le type d'image approprié que de regarder le type MIME The Fournitures client:

$info = getimagesize($_FILES['userfile']['tmp_name']);
if ($info === FALSE) {
    die("Couldn't read image");
}
if (($info[2] !== IMAGETYPE_PNG) && ($info[2] !== IMAGETYPE_JPEG)) {
    die("Not a JPEG or PNG");
}


3 commentaires

Il est possible qu'un fichier soit valide GIF et contenir du code PHP en même temps. Ainsi, getimagesize () ne donnera pas une grande protection réelle.


@Andre: tout ce qui peut contenir du texte peut contenir du code PHP. Au moins avec des images, le PHP ne sera pas exécuté, sauf si la configuration du serveur Web est incroyablement mauvaise.


Je recode habituellement l'image à BMP et retour à l'extension d'origine à l'aide de Imagick - Ceci se débarrasse de tout code malveillant dans ce fichier image.



1
votes

Concernant n ° 2, j'ai lu sur php.net ( Documentation de la Fonction getimagesize () ):

Ne pas utiliser getimagesize () pour vérifier qu'un fichier donné est une image valide. Utilisez une solution construite à des fins telle que l'extension FileInfo à la place.


0 commentaires