# Comprendre les méthodes `open()`, `verify()` et `load()` de Pillow sous l'angle de la sécurité Le téléchargement d'images n'est pas simplement « recevoir un fichier image » ; c'est **faire passer une entrée externe à un décodeur (parseur)**. Ainsi, les trois méthodes de Pillow sont plus importantes par *lorsqu'elles sont appelées* (c’est-à-dire *quand on ouvre la surface d'attaque*). --- ## `open()` n'est pas une fonction « qui charge les pixels » {#sec-2e015f3fe462} `Image.open()` fonctionne de façon **lazy**. Il ouvre le fichier, l’identifie, mais **les données de pixels peuvent ne pas être lues**. Le descripteur de fichier peut rester ouvert. En pratique, l’usage sécurisé de `open()` est simple : * Utiliser `open()` pour obtenir des informations légères comme le format, la largeur/hauteur * Appliquer des politiques de blocage : formats autorisés, résolution maximale, taille de fichier maximale * Passer à l’étape suivante (vérification/décodage) En d’autres termes, `open()` sert à **extraire les informations de décision avant le décodage**. --- ## Que garantit `verify()` et que ne garantit pas-il ? {#sec-bb315850bac9} `verify()` de Pillow tente de détecter si le fichier est corrompu, mais **ne décodera pas les données d'image**. En cas de problème, une exception est levée, et pour continuer à utiliser l'image, il faut la rouvrir. Deux conclusions de sécurité : * **Avantage** : éviter le décodage (tâche lourde) tout en filtrant rapidement les fichiers corrompus * **Limite** : passer `verify()` ne signifie pas *sécurité* ; c’est seulement que le fichier ne semble pas gravement corrompu. Des problèmes peuvent apparaître lors de `load()`. --- ## `load()` est dangereux s’il est appelé sans précaution dans la phase de vérification {#sec-1eb3249bd446} `load()` effectue réellement le **décodage (y compris la décompression)** et charge les pixels en mémoire. C’est immédiatement une surface d’attaque DoS (exhaustion des ressources), même si le fichier semble petit. Pillow gère le risque de « décompression de printemps » en déclenchant des exceptions ou en appliquant des seuils de protection (ex. 128 MPx). Django, pour la même raison, utilise `verify()` plutôt que `load()` lors de la validation du téléchargement d’images. Le code source contient un commentaire : *« load() charge l’image entière en mémoire, ce qui constitue un vecteur DoS »*. --- ## En Django/DRF : appeler `verify()` dans `ImageField` peut être redondant {#sec-c03f143819d2} La validation de `ImageField` dans les formulaires Django exécute déjà `Image.open()` + `verify()`. Le `serializers.ImageField` de DRF délègue également la validation à Django. Donc, si vous utilisez déjà `serializers.ImageField` : * Appeler `verify()` dans `validate()` pour vérifier la corruption est **généralement redondant**. * Si vous avez besoin d’une validation métier ou d’une sécurité supplémentaire, envisagez de recevoir le fichier via `FileField` et de concevoir votre propre pipeline de validation. --- ## Comment garantir la sécurité des fichiers téléchargés par l’utilisateur {#sec-bafb5e21c1fb} ![Diagramme de traitement sécurisé des fichiers téléchargés](/media/editor_temp/6/489648ac-eb83-4132-808b-f3ce0e07c366.png) La réponse la plus réaliste est la suivante : **Ne pas utiliser le fichier original tel quel, mais le décoder sur le serveur, puis le réenregistrer sous un nouveau fichier**. * Lire les informations légères avec `open()` (format, dimensions) et appliquer un premier blocage * Utiliser `verify()` pour éliminer les fichiers manifestement corrompus * Pour les fichiers qui passent, décoder dans un environnement limité et normaliser les pixels en RGB/RGBA * Réencoder dans le format choisi par le serveur et créer un nouveau fichier * Le service ne stocke/servent que le fichier réencodé Cette stratégie permet de contrôler la forme finale de la sortie et d’éliminer la plupart des métadonnées inutiles ou des structures anormales. Cependant, le réencodage implique toujours un décodage comparable à `load()`. Il faut donc mettre en place des garde-fous de mémoire (limite de pixels, mémoire) et, idéalement, exécuter le processus dans un worker ou un processus isolé. --- ## Résumé {#sec-7d348ef3294d} * `open()` : étape d’identification et de lecture d’informations légères (les pixels ne sont pas encore chargés) * `verify()` : filtre de corruption initial (sans décodage, nécessite une réouverture pour l’usage) * `load()` : point où le décodage et l’utilisation de la mémoire commencent (à éviter en masse dans la validation) * Solution pratique pour la sécurité du téléchargement : **confiance uniquement sur le fichier réencodé par le serveur** (avec limites/isolement requis) **Articles connexes** : - [Comment les développeurs voient les fichiers image ? Décomposons un fichier image](/ko/whitedec/2026/1/14/developer-view-image-file-common-structure/) - [Guide de sécurité du téléchargement d’images Django : traiter efficacement sans faire planter le serveur](/ko/whitedec/2026/1/13/django-image-upload-security-guide/) - [python-magic : la méthode la plus pratique pour détecter le type de fichier par son contenu plutôt que son extension](/ko/whitedec/2026/1/15/python-magic-file-type-detection/)