python-magic : la méthode la plus pratique pour se fier au contenu du fichier plutôt qu’à l’extension

Lorsque vous ajoutez une fonction de téléversement d’images à votre serveur, vous finirez un jour par rencontrer ces exigences.

  • « .png s’est bien téléversé… est-ce vraiment un PNG ? »
  • « Il faut d’abord savoir si le fichier est une image ou un document »
  • « Avant d’utiliser un parseur externe (Pillow/OpenCV), je veux au moins vérifier le type »

À ce moment-là, le point de départ le plus solide est le contenu du fichier, pas son extension. Et l’outil le plus simple pour obtenir cette « détection basée sur le contenu » est python-magic.


Que fait python-magic ?

python-magic est un wrapper Python pour la bibliothèque C libmagic. Cette dernière analyse les têtes (les premiers octets) d’un fichier pour en identifier le type. Cette fonctionnalité est également disponible via la commande Unix file.

En résumé :

  • file (commande Linux) = interface en terminal
  • libmagic = moteur central (logique de détection)
  • python-magic = wrapper léger pour appeler libmagic depuis Python

Cet article se concentre sur python-magic et explique de façon structurée comment ce moteur « devine » le type de fichier.


Comment fonctionne le moteur principal (libmagic) ?

Diagramme de fonctionnement de la bibliothèque libmagic

La nature de libmagic est simple.

« Il lit une base de données de règles de détection de type de fichier, examine les octets du fichier selon ces règles et en tire la conclusion la plus plausible. »

Cette base de données est la magic database (DB de motifs magiques) utilisée conjointement par file et libmagic. Elle est généralement installée sous forme compilée (magic.mgc).

1) Le « fichier magique » est un ensemble de règles

Ces règles se composent essentiellement de :

  • Où regarder (offset : position dans le fichier)
  • Comment lire (type : octet/chaîne/entier, etc.)
  • Avec quoi comparer (valeur attendue/motif)
  • Quel résultat donner (message/MIME, etc.)

Le manuel de file décrit ces « magic patterns ». Chaque règle est testée ligne par ligne, et si la condition est satisfaite, elle descend vers des tests plus spécifiques, formant une structure hiérarchique.

Pour en savoir plus sur la commande file de Linux, cliquez sur le lien ci‑dessous.

Découvrir la commande file de Linux

2) La base de données de règles existe en version texte et compilée

La DB peut être un ensemble de fragments texte lisibles par l’homme, mais pour des raisons de performance, elle est souvent fournie sous forme compilée (.mgc).

3) En fin de compte, on regarde le contenu, pas l’extension

file est un détecteur de type qui se base sur le contenu plutôt que sur l’extension, une philosophie ancienne. python-magic apporte cette philosophie en une seule ligne de code Python.


Comment utiliser python-magic ?

Il existe deux schémas d’utilisation courants.

1) Obtenir le type MIME (le plus pratique)

Pratique pour le traitement des téléversements, le routage, les logs/métriques.

import magic

mime = magic.from_file("upload.bin", mime=True)
print(mime)  # Exemple : image/png

python-magic fournit l’identification de type de fichier basée sur libmagic, comme le fait la commande file.

2) Détecter directement à partir d’un buffer (avantage pour les flux de téléversement)

Souvent, avant de sauvegarder sur disque, on veut rapidement examiner les premiers octets.

import magic

with open("upload.bin", "rb") as f:
    head = f.read(4096)

mime = magic.from_buffer(head, mime=True)
print(mime)

(La détection basée sur le buffer est idéale comme filtre préliminaire avant le stockage.)


Pourquoi est-ce utile pour les développeurs ?

1) Première ligne de défense pour la validation des téléversements

  • Ne pas se fier uniquement à l’extension
  • Vérifier rapidement si le fichier peut être traité comme une image

2) Point de bifurcation dans le pipeline de traitement

  • Si c’est une image : passer par le pipeline de redimensionnement/miniature
  • Si c’est un PDF/ZIP : déléguer à un autre worker
  • Si le type est inconnu : isoler/refuser/valider davantage

3) Réduire les coûts avant d’appeler un « décodage lourd »

Les décoders comme Pillow sont puissants mais coûteux en mémoire/CPU et exposent des surfaces d’attaque. python-magic permet de décider rapidement si l’appel est justifié.

Point clé : libmagic est un outil de détection/estimation. Pour une sécurité complète (blocage de charge utile malveillant, etc.), des vérifications supplémentaires (liste blanche, limite de taille, décodage sandbox) sont nécessaires.


En résumé : python-magic est la façon la plus légère d’apporter la détection de type de fichier en code {#sec-3b1611aa0fb2}

python-magic ne traite pas les images, mais indique rapidement comment les traiter.

  • Moteur : libmagic (comme file)
  • Méthode : base de règles + analyse d’octets
  • Utilité : validation de téléversements, routage, réduction de coûts

Maîtriser cette approche permet de mettre en place un filtre → bifurcation → protection même dans des environnements où les bibliothèques sont limitées.


Prochaine lecture ?

  • Que garantissent respectivement open(), load() et verify() de Pillow (PIL) ? Quand et comment les utiliser ? Nous les détaillerons.

Lire aussi