Question

Je travaille sur un script qui traitera les téléchargements des utilisateurs sur le serveur. En tant que couche de sécurité supplémentaire, j'aimerais connaître:

Existe-t-il un moyen de détecter la véritable extension / type de fichier d'un fichier et de s'assurer qu'il ne s'agit pas d'un autre type de fichier masqué avec une extension différente?

Existe-t-il un tampon d'octet ou un identifiant unique pour chaque type / extension?

J'aimerais pouvoir détecter que quelqu'un n'a pas appliqué une extension différente sur le fichier qu'il télécharge.

Merci,

Était-ce utile?

La solution

Pas vraiment, non.

Vous devrez lire les premiers octets de chaque fichier et l’interpréter comme un en-tête pour un ensemble fini de types de fichiers connus. La plupart des fichiers ont des en-têtes de fichier distincts, des métadonnées dans les premiers octets ou des premiers kilo-octets dans le cas des fichiers MP3.

Votre programme devra simplement essayer d'analyser le fichier pour chacun de vos types de fichiers acceptés.

Pour mon programme, j’envoie l’image téléchargée à imagemagick dans un bloc try-catch et, si elle explose, j’imagine que c’est une mauvaise image. Cela devrait être considéré comme peu sûr, car je charge des données binaires arbitraires (fournies par l'utilisateur) dans un programme externe, qui est généralement un vecteur d'attaque. Ici, je fais confiance à imageMagick pour ne rien faire pour mon système.

Je vous recommande d'écrire vos propres gestionnaires pour les types de fichiers significatifs que vous souhaitez utiliser, afin d'éviter tout vecteur d'attaque.

Edit: je vois en PHP qu'il existe des outils pour le faire pour vous.

De plus, les types MIME correspondent à ce que le navigateur de l'utilisateur considère comme étant le fichier. Il est pratique et utile de les lire et de les appliquer dans votre code, mais ce n'est pas une méthode sécurisée, car toute personne qui vous envoie de mauvais fichiers simulera facilement les en-têtes MIME. Il s’agit en quelque sorte d’une défense de première ligne de garder votre code qui attend d’un fichier JPEG qu’il utilise, mais si quelqu'un incorpore un virus dans un fichier .exe et le nomme JPEG, il n'y a aucune raison de ne pas avoir usurpé le type MIME.

Autres conseils

PHP utilise plusieurs méthodes pour lire le contenu d'un fichier afin de déterminer son type MIME, en fonction de la version de PHP utilisée:

Consultez les fonctions Fileinfo si vous utilisez PHP 5.3. +

$finfo = finfo_open(FILEINFO_MIME); 
$type = finfo_file($finfo, $filepath);
finfo_close($finfo);  

Vous pouvez également consulter mime_content_type pour les versions antérieures.

$type = mime_content_type($filepath);

Notez que simplement valider le type de fichier ne suffit pas si vous voulez être vraiment sécurisé. Quelqu'un pourrait, par exemple, télécharger un fichier JPEG valide exploitant une vulnérabilité dans un moteur de rendu courant. Pour vous protéger de cela, vous aurez besoin d’un scanner de virus bien entretenu.

PHP a un superglobal $ _ FILES qui contient des informations telles que la taille et le type de fichier. On dirait que le type est pris comme une sorte d'en-tête, pas une extension, mais je peux me tromper.

Vous en trouverez un exemple sur le site w3schools .

Je vais tester si cela peut être trompé quand j'en ai l'occasion.

MISE À JOUR:

Tout le monde le savait probablement, mais $ _FILES peut être trompé. J'ai pu le déterminer de cette façon:

$arg = escapeshellarg( $_FILES["file"]["tmp_name"] );
system( "file $arg", $type );
echo "Real type:  " . $type;

Il utilise essentiellement la commande fichier d'Unix. Il existe probablement de meilleures méthodes, mais je n'ai pas utilisé PHP depuis un moment. J'évite généralement d'utiliser des commandes système si possible.

qui pourraient encore être forgés. Je ferais en sorte que vous ne puissiez pas (ou ne fassiez pas) exécuter automatiquement un fichier téléchargé sur le serveur.

J'aurais également un détecteur de virus / logiciels espions et le laisser effectuer le travail à votre place.

vous pouvez utiliser le code ci-dessous qui vous donne le type MIME si vous avez changé l'extension, puis aussi

$finfo = finfo_open(FILEINFO_MIME_TYPE);
echo $mime = finfo_file($finfo, $_FILES['userfile']['tmp_name']);
finfo_close($finfo);

Utilisateurs Windows: modifiez simplement php.ini et décommentez cette ligne:

extension=php_fileinfo.dll

N'oubliez pas de redémarrer Apache pour que le nouveau fichier php.ini prenne effet.

Dans * nix, les deux premiers octets du fichier vous indiquent (voir & "nombre magique &"). Sous Windows, cela peut parfois être vrai (& Quot; informations d'en-tête & Quot;). C'est finalement O.S. dépendante.

Les exécutables ont en général une & signature; " sur les premiers octets; Je trouve cependant difficile de déterminer vraiment le type de fichier.

Quels types de fichiers attendez-vous? Peut-être pourriez-vous vérifier qu'il est conforme à vos attentes et rejeter tout le reste.

D'autres ont déjà mentionné FileInfo, qui, à mon avis, est la solution correcte, mais je vais l'ajouter au cas où vous ne pourriez pas l'utiliser pour une raison quelconque. La plupart (tous?) * Les distributions nix incluent une commande appelée file qui, lorsqu'elle est exécutée sur un fichier, affichera son type. Il dispose d'un commutateur permettant de générer la sortie dans un format lisible par l'homme (par défaut) ou le type MIME. Vous pouvez demander à votre script d’appeler ce programme sur le fichier téléchargé et de lire le résultat. Encore une fois, ce n'est pas l'approche préférée. Si vous utilisez Windows, cet utilitaire est disponible via Cygwin.

La vérification du type MIME est-elle simplement suffisante? Je suppose que changer l’extension d’un fichier ne change pas le type MIME?

Le type MIME est-il un indicateur suffisamment puissant pour passer ici?

Merci pour toutes les réponses reçues jusqu'à présent.

  

La vérification du type MIME est-elle simplement suffisante? Je suppose que la modification de l'extension d'un fichier ne change pas le type MIME? Le type MIME est-il un indicateur suffisamment puissant pour pouvoir suivre cette étape?

Cela dépend vraiment de son utilisation.

  • Si vous fournissez des ajouts et des téléchargements, rien ne compte car il ne s'exécute pas.
  • Si cela est géré par le serveur Web, alors cela dépendra de la configuration du serveur Web, bien que sujette à la plupart des autres commentaires.
  • S'il s'agit d'une image, elle s'affichera ou non, ou sera la cible des exploits de la bibliothèque d'images. Mais seulement ceux-là.
  • Quelque chose comme un fichier pdf peut ne pas affecter votre serveur, mais plutôt l'ordinateur de la personne accédant au fichier.
  • Si cela va être passé à une fonction comme & "system () &"; puis nous revenons au comportement du système d'exploitation - comme s'il s'agissait de & "double-clic sur &"; et l'extension du fichier pourrait même être considérée.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top