# Sicherheitsaspekte von Pillow: `open()`, `verify()` und `load()` Das Hochladen von Bildern bedeutet nicht einfach, eine Bilddatei zu empfangen – es geht darum, **externe Eingaben an einen Decoder (Parser) weiterzuleiten**. Deshalb sind die drei Pillow‑Methoden nicht nur funktionale Beschreibungen, sondern vor allem entscheidend, **wann** sie aufgerufen werden (also wann die Angriffsfläche geöffnet wird). --- ## `open()` ist keine „Pixel‑Lade‑Funktion“ {#sec-2e015f3fe462} `Image.open()` arbeitet **lazy**(verzögert). Das bedeutet, die Datei wird lediglich geöffnet und identifiziert, **Pixel‑Daten werden noch nicht gelesen**. Der Datei-handle kann dabei offen bleiben. In der Praxis ist die sichere Verwendung von `open()` sehr einfach: * Mit `open()` Format, Breite/Größe und andere **leichte Informationen** ermitteln * Durch Richtlinien blockieren: erlaubte Formate, maximale Auflösung/Pixelzahl, Upload‑Größenbeschränkung * Danach die eigentliche Validierung/Decodierung durchführen Kurz gesagt: `open()` dient als Werkzeug, um **vor der Decodierung prüfbare Informationen zu extrahieren**. --- ## Was garantiert `verify()` und was nicht? {#sec-bb315850bac9} `verify()` versucht, festzustellen, ob die Datei **beschädigt** ist, ohne jedoch die Bilddaten zu decodieren. Bei Problemen wird eine Ausnahme ausgelöst, und um das Bild weiter zu benutzen, muss es **erneut geöffnet** werden. Aus Sicht der Sicherheit lassen sich zwei Punkte festhalten: * **Vorteil:** Durch das Vermeiden der Decodierung (ein aufwändiger Prozess) lassen sich schnell „beschädigte“ Dateien aussortieren. * **Grenze:** Ein erfolgreicher `verify()`-Aufruf bedeutet nicht, dass die Datei völlig sicher ist – es zeigt lediglich, dass sie **nicht sofort stark beschädigt** erscheint. Probleme können erst bei `load()` sichtbar werden. --- ## `load()` ist gefährlich, wenn es in der Validierung zu früh aufgerufen wird {#sec-1eb3249bd446} `load()` führt die eigentliche **Decodierung (inkl. Entpackung)** durch und lädt die Pixel in den Speicher. Dieser Schritt ist sofort ein potenzieller DoS‑Angriffspunkt, weil die Datei zwar klein erscheinen kann, aber nach der Decodierung sehr groß wird. Pillow warnt vor dem „Decompression-Bomb“-Risiko und hat Schutzmechanismen mit Standard-Schwellenwerten (z. B. etwa 128 Mpx). Django nutzt aus demselben Grund `verify()` statt `load()` in der Bild‑Upload‑Validierung. In der Quelle steht explizit: *„load() lädt das gesamte Bild in den Speicher und ist ein DoS‑Vektor.“* – und danach wird `Image.open()` gefolgt von `verify()` aufgerufen. --- ## Django/DRF: `ImageField` und das doppelte `verify()` {#sec-c03f143819d2} Django‑Formulare führen intern `Image.open()` + `verify()` aus. Auch `serializers.ImageField` von DRF delegiert die Validierung an Django. Wenn Sie bereits `serializers.ImageField` nutzen, dann: * Ein zusätzlicher Aufruf von `verify()` in `validate()` ist meist **überflüssig**. * Für strengere Geschäfts‑ oder Sicherheitsprüfungen kann es sauberer sein, stattdessen ein `FileField` zu verwenden und die Validierung selbst zu gestalten. --- ## Wie kann man die Sicherheit von hochgeladenen Dateien gewährleisten? {#sec-bafb5e21c1fb} ![Diagramm zur sicheren Verarbeitung von hochgeladenen Dateien](/media/editor_temp/6/489648ac-eb83-4132-808b-f3ce0e07c366.png) Die praktischste Lösung lautet: 1. **`open()`**: Leichte Infos (Format, Größe) auslesen und mit Richtlinien blockieren. 2. **`verify()`**: Offensichtlich beschädigte Dateien entfernen. 3. **Decodieren**: In einer kontrollierten Umgebung (z. B. Worker/isolierter Prozess) decodieren und in ein Standard‑Pixelformat (RGB/RGBA) normalisieren. 4. **Neu‑Kodieren**: Das Ergebnis in einem vom Server gewählten Format speichern. 5. **Nur die neu erzeugte Datei** wird gespeichert und ausgeliefert. Vorteil: Der Server behält die Kontrolle über das Endformat und kann unerwünschte Metadaten oder ungewöhnliche Strukturen entfernen. Nachteile: Die Neu‑Kodierung beinhaltet immer noch einen `load()`‑ähnlichen Schritt. Daher sollten **Pixel‑/Speicher‑Grenzen** gesetzt und die Verarbeitung idealerweise in einem isolierten Prozess stattfinden. --- ## Fazit {#sec-7d348ef3294d} * **`open()`** – Identifikation + leichte Infos (Pixel noch nicht geladen) * **`verify()`** – Erster Filter für Beschädigungen (ohne Decodierung, für die Weiterverwendung erneut öffnen) * **`load()`** – Beginn der Decodierung und Speicher‑Nutzung (in der Validierung zu vermeiden) * **Sicherer Upload** – Server‑seitiges Neu‑Kodieren (mit Grenzen/Isolation) **Weiterführende Artikel**: - [Wie Entwickler Bilddateien sehen: Eine Analyse](/ko/whitedec/2026/1/14/developer-view-image-file-common-structure/) - [Django‑Bild‑Upload‑Sicherheits‑Guide](/ko/whitedec/2026/1/13/django-image-upload-security-guide/) - [python‑magic: Dateityp‑Erkennung ohne Dateiendung](/ko/whitedec/2026/1/15/python-magic-file-type-detection/)