web-dev-qa-db-fra.com

Est-ce que la modification de l'extension de fichier d'un exécutable téléchargé en .png le rend sûr?

Un de mes collègues a un site Web personnel dans lequel il permet aux utilisateurs de télécharger quoi que ce soit dans une certaine taille,

mais avant le téléchargement réel, il vérifie l'extension du fichier:

if ( $type == 'image/gif'){
  $ext = '.gif';
} elseif ( $type == 'image/jpeg'){
  $ext = '.jpg';
} elseif ( $type == 'image/png' ){
  $ext= '.png';
}  else {
  $ext = '.png';  
}

Il me dit qu'en faisant toutes les images de fichiers aucun mal ne peut être fait au serveur.

par exemple :

  evilscript.evil

deviendrait :

evilscript.png

Et être ainsi rendu inutile. Y a-t-il du vrai dans ses affirmations?

34
Peter verleg

Il existe essentiellement deux façons principales dont un fichier téléchargé peut être nuisible: en étant exécuté (en tant que script ou binaire) ou en étant exécuté/utilisé dans une application et en abusant d'un exploit (par exemple, un MP3 téléchargé qui est ensuite ouvert par un utilisateur spécifique). joueur, abusant d'une faiblesse connue).

En d'autres termes, tout dépend de ce qui se passe avec le fichier après le téléchargement. Si quelqu'un est capable de télécharger un script Perl, mais que le serveur n'exécute jamais les fichiers téléchargés ou même que Perl n'est pas installé, rien ne peut jamais se produire. En général: si vous vous assurez que le fichier téléchargé n'est jamais exécuté ou interprété, vous serez en sécurité.

Renommer les fichiers n'aide qu'à une chose: sur certains systèmes d'exploitation, certaines extensions de fichier peuvent être liées à une application spécifique. Si vous renommez le fichier, vous pouvez empêcher l'ouverture du fichier avec une application liée. Mais selon le système et la configuration, les fichiers téléchargés peuvent toujours être ouverts avec une application vulnérable. Pour rester dans l'exemple ci-dessus: si un fichier téléchargé est ouvert avec un lecteur MP3, même si vous le renommez en song.png, il serait toujours en mesure d'exploiter une faiblesse du joueur (sauf si le joueur a sa propre couche de vérification et, par exemple, n'accepte que .mp3 des dossiers).

Les fichiers renommés ne sont pas des images soudainement, juste à cause du changement de nom. Sur Unix et les systèmes similaires, il existe même la commande file pour analyser le type/type MIME d'un fichier.

Conclusion: à mes yeux, il n'y a qu'une seule chose que vous pouvez faire. Soyez très précis dans votre configuration sur ce qui peut et sera fait avec les fichiers téléchargés. Toutes les bibliothèques, extensions ou applications acceptant ces fichiers doivent toujours être mises à jour vers la dernière version.

49
Draugr

Non. Le fait de renommer un fichier n'augmente pas la sécurité.

Il me dit que en faisant toutes les images des fichiers aucun mal ne peut être fait au serveur.

par exemple, evilscript.evil deviendrait evilscript.png

Lorsque vous renommez evilscript.evil à evilscript.png vous ne le transformez pas en image. Vous changez simplement son nom. Généralement, un nom de fichier n'est pas pertinent. Ce n'est qu'un nom donné à un bloc de données, rien de plus.

Si vous pouvez exécuter un script téléchargé, vous pouvez probablement le faire quel que soit son nom. Si vous ne le pouvez pas, le téléchargement d'un script malveillant ne nuit pas au système, car le script ne sera pas exécuté de toute façon.

Cependant, cela peut empêcher l'exécution accidentelle d'un fichier. La seule protection que le renommage pourrait fournir est la protection contre un lancement accidentel par l'Explorateur Windows (ou un shell qui utilise de la même manière des extensions de fichier). Donc renommer virus.exe en virus.exe~ aide réellement lorsque vous touchez accidentellement Enter dessus.

Les shells Unix utilisent des formats de fichier au lieu d'extensions. Par exemple, vous pouvez enregistrer un script en tant que evilscript.png et l'exécuter avec un shell Linux, à condition que le fichier dispose de l'autorisation "exécuter". En termes de sécurité, il est généralement préférable de contrôler les autorisations de fichiers plutôt que les noms de fichiers.

12
enkryptor

Il existe deux problèmes, la protection contre les attaques directes sur le serveur et la protection contre les attaques sur d'autres clients (qui à leur tour peuvent conduire à des attaques sur le serveur)

D'abord le serveur, lorsqu'un client demande un fichier, le serveur doit décider s'il doit le servir ou l'exécuter d'une manière ou d'une autre. Cette décision peut dépendre de divers facteurs, notamment.

  1. L'extension du fichier
  2. Le répertoire dans lequel se trouve le fichier
  3. Indique si le bit exécutable est défini.

Je ne suis au courant d'aucun serveur Web effectuant une inspection de contenu côté serveur, mais je ne peux pas exclure qu'il en existe un.

Idéalement, sur le serveur, vous ne placeriez pas les fichiers fournis par l'utilisateur dans un répertoire où l'exécution de script est autorisée en premier lieu, mais restreindre l'extension de fichier est probablement une politique de "défense en profondeur" judicieuse au cas où un fichier se retrouverait par inadvertance dans le mauvais endroit.

Si le serveur décide de servir le fichier, il doit alors décider quel type de mime envoyer. Les serveurs Afaict choisissent généralement le type MIME en fonction de l'extension de fichier. Le client doit alors décider quoi faire du fichier. Il doit baser cela sur le type MIME envoyé par le serveur mais dans la pratique, il peut plutôt le baser sur l'extension de fichier ou sur l'inspection du contenu du fichier,

Si le navigateur choisit de traiter le fichier comme un type pouvant impliquer des scripts côté client, le domaine à partir duquel le fichier est servi devient important. Si le fichier est servi à partir de votre domaine principal, le script peut probablement lire les cookies que vous définissez et les utiliser pour usurper l'identité de l'utilisateur.

Je crois qu'une restriction d'extension de fichier devrait faire partie de la stratégie de sécurité, mais pas tout. Le stockage dans des répertoires qui interdisent l'exécution de scripts, l'application de l'extension de correspondance de contenu et l'utilisation d'un nom de domaine distinct doivent tous être considérés comme faisant partie de la stratégie de défense globale.

2
Peter Green

Vérifier la seule extension d'un fichier téléchargé ne suffit pas. Par exemple: vérifiez la réponse sur cette question .

Une proposition: il existe un moyen plus fiable de connaître le type d'un fichier. Si votre ami exécute le serveur sur une machine Unix, vous pouvez utiliser la commande ' file ' qui inspecte le contenu du fichier pour déterminer le format.

2
George Gkitsas

C'est sûr.

On peut toujours faire passer clandestinement du code exécutable à l'intérieur d'une image:

  • Téléchargez simplement votre code PHP avec une autre extension.
  • Mettez-le dans des métadonnées, telles que EXIF.
  • Utilisez des pixels spécifiquement colorés de telle sorte que leur représentation binaire soit votre code PHP code, qui survivra au réencodage (j'ai en fait vu celui-ci dans la vraie vie, exploité en utilisant: https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/ ).

Vous devez donc déjà supposer que le fichier - contenu de votre fichier n'est pas sûr lorsqu'il est fourni par l'utilisateur. Même si vous ré-encodez l'image, et même si vous convertissez des formats, c'est toujours une image alors ne l'exécutez pas sanglante. Si votre serveur Web (comme Apache ou Nginx) l'exécute via l'interpréteur PHP, alors quelqu'un trouvera un moyen de déclencher PHP pour faire quelque chose de méchant). En forçant l'extension à être l'une des quelques extensions de la liste blanche, vous pouvez dire à votre serveur Web qu'il s'agit d'une image (non exécutable) et qu'elle ne doit pas passer par l'interpréteur.

Il y a, bien sûr, certains risques liés à connaître:

  • Votre utilisateur peut mettre des octets nuls ou d'autres choses amusantes dans le nom de fichier, ce qui pourrait lui permettre de choisir son extension après tout.
  • Votre utilisateur peut essayer d'utiliser la traversée de chemin si vous le laissez choisir le nom de fichier, ce qui pourrait lui permettre de faire toutes sortes de choses.
  • Vous pourriez faire une erreur dans la configuration du serveur Web et tout est exécuté via l'interpréteur quelle que soit l'extension (je l'ai déjà vu: c'est un bug silencieux, car PHP génère littéralement tout ce qu'il ne fait pas) 'reconnaissent pas, donc les images auront la même apparence avant et après PHP interprétation).
  • Le fichier peut contenir un exploit pour un décodeur spécifique, par exemple si vous savez que l'administrateur peut afficher votre image et qu'il utilise un navigateur doté d'une visionneuse PNG vulnérable, vous pouvez télécharger une image PNG qui exploite cette vulnérabilité.

Les deux premiers sont faciles à résoudre: ne laissez jamais l'utilisateur choisir son nom de fichier, ou au moins ajoutez à la liste blanche un ensemble de caractères qui sont définitivement sûrs, tels que ^[a-zA-Z0-9_-]*$ (alphanumérique, trait de soulignement et trait d'union).

Le troisième peut être vérifié en plaçant un fichier appelé "test.png" quelque part et en mettant <?php echo "test1"; dedans. Lorsque vous demandez le fichier via curl, vous devriez voir le code complet. Si vous ne voyez que "test1", alors il est vulnérable.

Enfin, le dernier est difficile à vérifier et quelque peu hors de portée. Vous pouvez utiliser un antivirus côté serveur, mais les antivirus ne détectent que quelques cas courants et ne seront généralement pas en mesure de détecter toutes les variantes d'une vulnérabilité, s'ils connaissent la vulnérabilité en premier lieu. L'utilisateur doit, idéalement, mettre à jour son système et ne pas exécuter de logiciel vulnérable. Mais si vous êtes dans un environnement à haute sécurité, vous devez appliquer une défense en profondeur et faire des choses comme réencoder l'image, peut-être uniquement permettre aux utilisateurs de visualiser les images dans une machine virtuelle, etc. Mais cela est hors de portée pour cette question .

Résumé: Il y a certaines attaques connexes que vous n'avez pas montré comme étant atténuées, mais en considérant uniquement l'extrait de code tel que publié: cette partie est sûre.

1
Luc