Du hängst einen Screenshot aus dem Kundenportal an ein öffentliches GitHub-Issue oder ein Support-Ticket an und ziehst schnell einen Verpixelungs-Filter über deine IBAN oder einen geheimen API-Schlüssel. Oder du teilst ein Smartphone-Foto aus deinem Heimnetzwerk-Schrank, ohne zu ahnen, dass im Datei-Header deine exakte Wohnadresse als GPS-Koordinate samt Seriennummer des Geräts gespeichert ist.
Sicheres Schwärzen überschreibt die betroffenen Bildpunkte in einem frischen HTMLCanvasElement komplett durch einfarbige Farbwerte oder Zufallsrauschen und kodiert das Gesamtbild anschließend neu. Durch dieses Re-Encoding fallen sämtliche Container-Metadaten wie JPEG-EXIF-Blöcke oder PNG-Textsegmente restlos weg. Diese Methode schützt Rasterbilder (PNG, JPEG, WebP); für Vektor-PDFs mit markierbarem Text muss die Seite vorab in ein reines Pixelbild umgewandelt werden.
Verpixeln und Weichzeichnen verschleiern Text nur optisch, vernichten die Information aber nicht mathematisch. Wirklich gelöscht sind sensible Bilddaten erst, wenn ihre Pixel vollständig überschrieben und alle Datei-Header beim Neu-Kodieren verworfen werden.
Warum lassen sich verpixelte Passwörter und Kontonummern oft wiederherstellen?
Ein klassischer Mosaik-Filter fasst jeweils einen Block von beispielsweise 10 × 10 Bildpunkten zusammen und ersetzt ihn durch den arithmetischen Helligkeitsmittelwert dieser 100 Pixel. Bei Gesichtern reicht das oft aus – bei kurzem Text in bekannten Systemschriften (Segoe UI, San Francisco, Inter, Consolas) ist dieses Verfahren jedoch mathematisch angreifbar.
Beim Angriff durch rendert ein Angreifer Kandidaten-Zeichen im exakt gleichen Blockraster und vergleicht die entstehenden Graustufenmuster. Weil Ziffern wie 1, 4 und 8 sehr unterschiedliche Schwarzanteile und Kantenpositionen besitzen, lässt sich eine verpixelte IBAN oder ein API-Token oft Zeichen für Zeichen rekonstruieren.
Selbst ein pechschwarzer Balken verrät noch ein letztes Detail, wenn er millimetergenau am ersten und letzten Buchstaben einrastet: Über eine schließt man Namen aus, die zu breit oder zu schmal für die Lücke sind. Ein leichter zufälliger Überstand (±3 bis 6 Pixel) links und rechts unterbindet auch diesen Rückschluss.
Wie Datei-Metadaten im Binärstrom stecken und beim Canvas-Export verschwinden
Kameras und Betriebssysteme legen Zusatzinformationen außerhalb der eigentlichen Bildpunkte in speziellen Container-Abschnitten ab:
- JPEG (
0xFF 0xD8): Direkt hinter der Startkennung liegen . Besonders tückisch: Manche älteren Bildprogramme schneiden zwar das Hauptbild zu, lassen aber das winzige, unbeschnittene Original-Vorschaubild (EXIF Thumbnail) imAPP1-Block unangetastet! - PNG (
89 50 4E 47): Speichert Erstellungssoftware, Zeitstempel (tIME), Kommentare (tEXt,iTXt) und seit neueren Standards aucheXIf-Blöcke als eigenständige Chunks.
Zeichnest du ein geladenes Bild per ctx.drawImage() auf ein neues <canvas>-Element, überträgt der Browser ausschließlich das rohe RGBA-Pixelraster und verwirft sämtliche ursprünglichen Datei-Segmente:
1// Prüft binäre JPEG-APP1-Segmente vorab und erzeugt eine bereinigte WebP-Datei2export function hasJpegExifSegment(fileBytes: Uint8Array): boolean {3 if (fileBytes.length < 4 || fileBytes[0] !== 0xff || fileBytes[1] !== 0xd8) {4 return false;5 }6 let offset = 2;7 while (offset + 4 <= fileBytes.length) {8 if (fileBytes[offset] !== 0xff) break;9 const marker = fileBytes[offset + 1];10 if (marker === 0xda || marker === 0xd9) break; // Bilddaten-Beginn (SOS) erreicht11 const segmentLength = (fileBytes[offset + 2] << 8) | fileBytes[offset + 3];12 if (marker === 0xe1) return true; // APP1 (EXIF / GPS / XMP) gefunden!13 offset += 2 + segmentLength;14 }15 return false;16}17
18export async function redactAndStripMetadata(19 img: HTMLImageElement,20 boxes: Array<{ x: number; y: number; width: number; height: number }>21): Promise<Blob> {22 const canvas = document.createElement("canvas");23 canvas.width = img.naturalWidth;24 canvas.height = img.naturalHeight;25 const ctx = canvas.getContext("2d");26 if (!ctx) throw new Error("Canvas-2D-Kontext nicht verfügbar");27
28 ctx.drawImage(img, 0, 0);29 ctx.fillStyle = "#09090b";30
31 for (const box of boxes) {32 // Überschreibt die Originalpixel im Zielpuffer unwiderruflich33 ctx.fillRect(box.x, box.y, box.width, box.height);34 }35
36 return new Promise<Blob>((resolve, reject) => {37 canvas.toBlob(38 (blob) => (blob ? resolve(blob) : reject(new Error("WebP-Export fehlgeschlagen"))),39 "image/webp",40 0.8641 );42 });43}Welches Schwärzungs-Verfahren ist wirklich sicher?
- Immer deckende Vollblöcke (
100 % Deckkraft) oder Zufallsrauschen wählen und links/rechts einige Pixel großzügiger über den Textrand hinausziehen - Auf iOS/Android niemals den Textmarker-Stift zum Schwärzen verwenden – selbst nach fünfmaligem Übermalen bleibt ein Restkontrast in den Farbkanälen messbar
- Für gestochen scharfe Software-Screenshots ohne Kompressionsränder PNG oder WebP statt stark komprimiertem JPEG wählen
- Keine ungeschwärzten Ausweise, Verträge oder privaten API-Schlüssel zum Bearbeiten auf fremde Online-Bildportale hochladen
- Nicht nur den unteren Teil eines Screenshots abschneiden, falls das Werkzeug alte
EXIF-Vorschaubilder im Datei-Header belässt - Keine sensiblen Zugangsdaten nur schwärzen, wenn sie bereits kurz öffentlich sichtbar waren – kompromittierte API-Keys immer zusätzlich im Backend widerrufen
Prüfe vor dem Absenden nicht nur die eigentliche Tabelle in der Bildmitte: Häufig verraten die Adresszeile des Browsers (Kunden-IDs oder Suchparameter in der URL), offene Nachbar-Tabs oder Benachrichtigungs-Banner am oberen Bildschirmrand genau die Information, die unten sorgfältig geschwärzt wurde.
Prüfpunkte vor dem Veröffentlichen eines geschwärzten Bildes
- Deckkraft 100 % sicherstellen: Nutze ein Werkzeug, das Pixel hart überschreibt und neu kodiert, statt halbtransparenter Zeichenstifte.
- Rand-Überstand einplanen: Ziehe den Balken etwas breiter als das Wort selbst, damit niemand aus der exakten Pixelbreite auf kurze Namen oder Postleitzahlen schließen kann.
- Adressleiste & Fenstertitel mitprüfen: Kontrolliere URL-Parameter, E-Mail-Adressen im Profil-Menü oben rechts und sichtbare Lesezeichenleisten.
- Bereinigten Export versenden: Lade wirklich die neu exportierte
-geschwaerzt-Datei hoch statt versehentlich die gleichnamige Originaldatei aus dem Download-Ordner zu erwischen.
Quellen und nächste Schritte
- Bishop Fox Security Research (Dan Petro) – Never Use Text Pixelation To Redact Sensitive Information (
UnredacterProof-of-Concept): bishopfox.com/blog/unredacter-tool-never-pixelation - CIPA DC-008-2023 – Exchangeable image file format for digital still cameras: Exif Version 3.0: www.cipa.jp/std/documents/download_e.html?DC-008-Translation-2023-E
- W3C Recommendation – Portable Network Graphics (PNG) Specification (Third Edition) — Ancillary Metadata Chunks (
tEXt,iTXt,eXIf): www.w3.org/TR/png-3/ - Weiterführend im Digital Garden: Willst du ein bereinigtes Bild komplett ohne Cloud oder WLAN an ein isoliertes Zweitgerät übergeben, nutze den optischen Bild-Stream im QR-Code-Generator & Webcam-Transfer oder lies in Offline-KI in Web-Apps, wie lokale Browser-Werkzeuge dauerhaft ohne Server auskommen.