Kurzfassung
Kernaussage: Kein Bildinhalt wird an den LokalPix-Server gesendet. Der Server liefert die Anwendung aus und stellt eine aggregierte Aufrufstatistik bereit; die eigentliche Bildverarbeitung findet auf dem Endgerät statt.
Datenfluss einer Konvertierung
- 1Seite laden
Beim Laden der Startseite kann der Browser HTML, CSS, JavaScript, Manifest, Symbol und Service Worker von derselben LokalPix-Adresse abrufen. Die Startseite liest zusätzlich
/api/stats. Die Technikseite selbst lädt nur HTML, CSS und gegebenenfalls das Symbol; sie führt kein App-JavaScript aus. - 2Datei auswählen
Die Dateiauswahl erfolgt über das native Datei-Auswahlfeld des Browsers. JavaScript erhält nur die vom Nutzer ausgewählten Dateien.
- 3Datei lokal prüfen
Dateityp, Dateigröße und Bildabmessungen werden im Browser geprüft. Bei SVG sucht die Anwendung nach festgelegten riskanten Elementen und Mustern und lehnt die Datei bei einem Treffer ab.
- 4Bild lokal dekodieren
Der Browser dekodiert die Datei über
createImageBitmapoder ein lokalesImage-Objekt. Die Quelle ist eine lokale Blob-URL, keine Serveradresse. - 5Neu zeichnen und codieren
Das Bild wird in ein Canvas gezeichnet.
canvas.toBlob()erzeugt PNG, JPG oder WebP. Für JPG wird zuvor ein weißer Hintergrund eingefügt. - 6Download
Die Ausgabedatei wird als temporäre Blob-URL im Browser bereitgestellt. Erst der Nutzer speichert sie über „Herunterladen“ auf seinem Gerät.
- 7Speicher freigeben
Beim Entfernen oder vollständigen Zurücksetzen widerruft die Anwendung zugehörige Blob-URLs. Alte Ausgabe-URLs werden nach erfolgreicher Neukonvertierung beziehungsweise beim Formatwechsel widerrufen. Zusätzlich ist ein Widerruf bei
beforeunloadregistriert; dessen Ausführung ist nicht in allen Browser-Lebenszyklen garantiert.
Bildverarbeitung und Formate
Eingaben
Akzeptiert werden JPEG/JPG, PNG, WebP, SVG und AVIF mit höchstens 25 MB pro Datei. Maximal 20 Dateien werden gleichzeitig in die Warteschlange aufgenommen. Leere oder allgemeine MIME-Angaben dürfen anhand einer bekannten Dateiendung ergänzt werden; ein ausdrücklich fremder MIME-Typ wird nicht durch die Endung überschrieben.
Abmessungsgrenzen
Erlaubt sind höchstens 16.384 Pixel pro Kante und insgesamt 40 Megapixel. Bei PNG, JPEG, WebP und AVIF versucht LokalPix, die Abmessungen bereits aus den ersten 512 Dateibytes auszulesen. Nach dem Dekodieren wird die Grenze erneut geprüft.
Ausgaben
PNG, JPG und WebP werden über die Canvas-Schnittstelle des Browsers erzeugt. Die Qualitätswahl beeinflusst JPG und WebP. AVIF wird nicht als Ausgabe angeboten, weil die Canvas-Unterstützung dafür nicht browserübergreifend zuverlässig ist.
Ausrichtungsmetadaten
Beim bevorzugten Dekodierweg fordert createImageBitmap mit imageOrientation: 'from-image' die Anwendung der in der Quelldatei hinterlegten Ausrichtung an. Beim Rückfall auf ein Image-Objekt ist das Verhalten browserabhängig. Die Wirkung einer EXIF-Ausrichtung kann dadurch in Abmessungen und Ausgabepixel einfließen, obwohl das ursprüngliche Metadatenfeld nicht ausdrücklich in die Ausgabedatei kopiert wird.
SVG-Sonderbehandlung
SVG ist ein XML-basiertes Dokumentformat und kann aktive oder externe Inhalte enthalten. LokalPix parst SVG im Browser und sucht nach einer im Quellcode definierten Denylist, unter anderem nach Skripten, Ereignisattributen, eingebetteten Fremdinhalten, Animationen, Stylesheets, externen href-Zielen, externen CSS-URLs, CSS-Imports, Expressions, maskierten Stilwerten und nicht zuverlässig auflösbaren CSS-Maßeinheiten. Bei einem Treffer wird die Datei abgelehnt; andernfalls wird die serialisierte SVG-Struktur weiterverarbeitet. Diese Prüfung reduziert das Risiko, ist aber keine vollständige Element- und Attribut-Allowlist und garantiert nicht die Erkennung jeder denkbaren aktiven SVG-Funktion.
Welche Netzwerkzugriffe erfolgen?
Startseite
GET /Lädt die Startseite und erhöht den aggregierten Seitenzähler.
GET /styles.cssLädt das lokale Design.
GET /app.mjsLädt die Bedien- und Konvertierungslogik.
GET /converter-core.mjsLädt Format-, Größen- und Dateinamenlogik.
GET /api/statsLiest Aufrufe heute, Aufrufe gesamt und Zählbeginn.
GET /sw.jsPrüft beziehungsweise installiert den Service Worker.
GET /manifest.webmanifestKann vom Browser für die installierbare Web-App angefordert werden.
GET /icon.svgKann als Website- oder App-Symbol angefordert werden.
Service-Worker-Installation und Wiederholungsaufrufe
Bei der Installation ruft cache.addAll() die Cache-Liste ab: /, /technik-datenschutz.html, /styles.css, /app.mjs, /converter-core.mjs, /manifest.webmanifest und /icon.svg. Spätere Abrufe statischer Dateien können aus Cache Storage beantwortet werden. Seitennavigationen bleiben network-first; bei einem Netzwerkfehler wird eine vorhandene Cachekopie verwendet. Die konkrete Anfragemenge hängt deshalb von Browser, HTTP-Cache und Service-Worker-Zustand ab.
Technikseite
Ein direkter Aufruf dieser Seite lädt HTML und CSS sowie browserabhängig /icon.svg. Die Seite selbst lädt weder app.mjs noch /api/stats und registriert keinen Service Worker. Ein bereits von der Startseite aktiver Service Worker kann ihre Navigation dennoch verarbeiten.
Die Anwendung enthält keine Analyse-, Werbe-, Social-Media-, Schriftarten- oder sonstigen Drittanbieter-Skripte. Ihre Content Security Policy erlaubt Skripte, Styles und Netzwerkverbindungen nur zur eigenen Herkunft. Vorschaubilder und Ergebnisse verwenden lokale blob:- beziehungsweise eingebettete data:-Quellen.
Abgrenzung: Technisch notwendige Vorgänge des Betriebssystems oder Browsers – beispielsweise DNS-Auflösung oder Zertifikatsprüfung – liegen außerhalb der Anwendungslogik und sind nicht mit einem Bild-Upload gleichzusetzen.
Besucherstatistik
Ein Seitenaufruf wird serverseitig gezählt, wenn eine GET-Anfrage für / oder /index.html eingeht. Der geprüfte Node-Anwendungscode greift nicht auf die im Socket verfügbare Client-IP zu, protokolliert sie nicht, setzt keine Cookies und speichert keine Gerätekennung. Jede HTTP-Verbindung offenbart die Quell-IP technisch mindestens dem Netzwerk- und Hosting-Stack; dessen Verhalten ist separat zu prüfen.
Eine neu angelegte, unveränderte Statistikdatei enthält:
- Datum des Zählbeginns,
- Gesamtzahl der Seitenaufrufe,
- Anzahl der Seitenaufrufe je Kalendertag in der Zeitzone Europe/Berlin.
Vorhandene Statistikdateien werden derzeit nicht gegen ein Schema validiert; bereits enthaltene zusätzliche Felder können bei späteren Schreibvorgängen erhalten bleiben. Bei einer fehlerhaften oder nicht lesbaren Statistikdatei fällt der Store auf einen neuen Zustand im Arbeitsspeicher zurück; ein späterer erfolgreicher Schreibvorgang kann die vorherige Datei ersetzen. Strukturell ungeeignete, aber parsebare Werte können die Statistik auch unverfügbar machen. Persistenz erfolgt best effort: Ein Schreibfehler wird gegenüber dem Seitenaufruf abgefangen; der aktualisierte Zähler kann dann nur lokal im Prozess vorliegen und bei einem Neustart verloren gehen.
Gesamtsumme und Zählbeginn bleiben bis zur administrativen Löschung oder Ersetzung der Statistikdatei erhalten. Tageswerte werden bei einem neuen gezählten Aufruf auf höchstens 370 vorhandene Datumsschlüssel reduziert. Dies ist keine zeitbasierte 370-Tage-Löschfrist; bei weniger als 370 Nutzungstagen können alte Werte bestehen bleiben. Bei erfolgreicher Persistenz wird die temporäre JSON-Datei mit Dateirechten 0600 angelegt und umbenannt. Verzeichnisrechte, Backups und privilegierte Systemzugriffe sind davon nicht erfasst. Der öffentliche Statistik-Endpunkt gibt nur den heutigen Wert, die Gesamtsumme und das Startdatum aus und erhält Cache-Control: no-store.
Wichtig: Auch der initiale Service-Worker-Vorabruf von / kann den Zähler erhöhen. Die Zählung unterscheidet außerdem nicht zwischen Menschen, Bots, mehrfachen Aufrufen oder wiederholtem Neuladen. Sie ist eine Aufrufstatistik, keine Messung eindeutiger Besucher.
Was wird wo gespeichert?
Auf dem Server
Statische Anwendungsdateien und die aggregierte Statistikdatei. Keine ausgewählten Bilder und keine konvertierten Bilder.
Im vom Browser verwalteten lokalen Speicher
Ausgewählte Dateien beziehungsweise Dateireferenzen, geprüfte SVG-Kopien, Vorschaubilder, Canvas-Inhalte und Ausgabe-Blobs während der laufenden Anwendungsinstanz. Je nach Browser und Betriebssystem können diese Daten im Arbeitsspeicher oder temporär auf dem lokalen Datenträger liegen. Die Anwendung widerruft URLs wie oben beschrieben; Browser und Betriebssystem steuern Ablage und tatsächliche Freigabe.
In Cache Storage
Der Service Worker speichert persistent Anwendungskomponenten wie HTML, CSS, JavaScript, Manifest und Symbol, bis Browserdaten gelöscht oder LokalPix-Caches durch eine Aktualisierung ersetzt werden. Bilddateien gehören nicht zur Cache-Liste. Bei Aktivierung löscht der Worker nur ältere Caches mit dem Präfix lokalpix-.
Im Download-Ordner
Nur wenn der Nutzer den Download auslöst, speichert der Browser die konvertierte Datei am vom Nutzer beziehungsweise Browser gewählten Ort.
Davon zu unterscheiden sind zwei Cache-Ebenen: Der Server antwortet für HTML mit Cache-Control: no-cache, für andere statische Dateien mit public, max-age=3600 und für /api/stats mit no-store. Der Service Worker nutzt für vorab gespeicherte Nicht-Navigationsressourcen cache-first.
LokalPix verwendet für die Konvertierung weder localStorage noch Cookies, IndexedDB oder ein Benutzerkonto.
Sicherheitsmaßnahmen
- Content Security Policy: Standardmäßig sind nur Ressourcen derselben Herkunft erlaubt; Objekte, fremde Frames und fremde Formularziele sind blockiert.
- Frame-Schutz:
frame-ancestors 'none'undX-Frame-Options: DENYweisen unterstützende Browser an, die Einbettung in andere Seiten abzulehnen. - MIME-Schutz:
X-Content-Type-Options: nosniffschränkt MIME-Sniffing insbesondere für Script- und Style-Ziele ein. - Referrer-Schutz:
Referrer-Policy: no-referrerunterbindet das Senden einer Referrer-Adresse. - Berechtigungen: Kamera, Mikrofon, Geolocation und Payment API werden per
Permissions-Policydeaktiviert. - Dateigrenzen: Anzahl, Dateigröße, Kantenlänge und Pixelzahl sind begrenzt.
- SVG-Prüfung: Dateien mit den im Quellcode aufgeführten riskanten Elementen, Referenzen oder Stilwerten werden abgelehnt.
- Keine schreibende Bild-API: Der Server akzeptiert nur
GETundHEAD; andere Methoden werden mit Status 405 zurückgewiesen.
Hosting- und Reverse-Proxy-Ebene
Der geprüfte Node-Anwendungscode liest oder persistiert keine Client-IP, setzt keine Cookies und nimmt keine Bilder entgegen. Jede Verbindung erreicht jedoch einen Netzwerk- und Hosting-Stack, der die Quell-IP technisch verarbeiten kann. Ein VPS-Anbieter, Reverse Proxy, CDN, eine Firewall, DDoS-Schutz, DNS-Dienst oder Systemprotokolle können zusätzliche Verbindungsdaten, Header oder Cookies verarbeiten beziehungsweise setzen.
Vor Veröffentlichung sollte deshalb separat dokumentiert und geprüft werden:
- welcher Hosting-Anbieter und Serverstandort verwendet wird,
- ob und wie lange Access- und Fehlerprotokolle gespeichert werden,
- ob IP-Adressen gekürzt oder vollständig vermieden werden können,
- welche Auftragsverarbeitungs- und Unterauftragnehmerbeziehungen bestehen,
- wie TLS, Backups, Updates, Zugriffsrechte und Löschfristen organisiert sind.
Diese Grenze ist entscheidend: „Keine Bild-Uploads“ ist eine Eigenschaft der Anwendung. Aussagen über vollständige Server-Protokollfreiheit sind erst nach Prüfung der konkreten Produktionsumgebung möglich.
Was diese Architektur nicht garantiert
- Ein kompromittierter Browser, eine schädliche Browser-Erweiterung oder ein kompromittiertes Endgerät liegt außerhalb der Kontrolle von LokalPix.
- Browser-Decoder können Sicherheitsfehler enthalten; Größenprüfungen reduzieren Risiken, ersetzen aber keine Browser-Updates.
- Die SVG-Prüfung ist eine vorsichtige Ablehnungslogik, keine formale Sicherheitszertifizierung jedes denkbaren SVG-Inhalts.
- Quell-EXIF-, IPTC- und XMP-Felder werden vom Anwendungscode nicht kopiert; die Rasterausgabe wird über Canvas neu codiert. Es gibt keine nachgelagerte Byte-Prüfung, Browser können eigene Metadaten erzeugen, und sichtbare beziehungsweise in Pixel eingebrannte Informationen bleiben erhalten.
- Die Ausgabequalität hängt vom Browser, Eingabeformat und gewählten Qualitätswert ab.
- Die technische Beschreibung ersetzt weder Datenschutz-Folgenabschätzung noch Rechtsprüfung, sofern eine solche im konkreten Einsatz erforderlich ist.
Empfohlene Prüfschritte
- Browser-Netzwerkprotokoll öffnen: Einen Erstbesuch mit leeren Browserdaten, einen Wiederholungsbesuch, den direkten Aufruf der Technikseite und einen Offline-Fall getrennt prüfen. Danach ein Bild auswählen und konvertieren; während Auswahl und Konvertierung darf keine Anfrage mit Bildinhalt erscheinen.
- Anfragen kontrollieren: Zulässig sind nur Ressourcen der eigenen Herkunft und lokale
blob:-URLs. Es dürfen keine Drittanbieter-Domains erscheinen. - Server-Routen prüfen: Der Quellcode in
server.mjsenthält keinen Upload-Endpunkt und akzeptiert nur GET und HEAD. - Konvertierungslogik prüfen:
public/app.mjsdekodiert, zeichnet und codiert die Bilder ausschließlich über Browser-APIs. - Statistik prüfen:
stats-store.mjssowie die produktive Statistikdatei auf reguläre Zählerfelder, unerwartete Zusatzfelder, Dateirechte, Backups und administrative Löschung prüfen. - Service Worker prüfen:
public/sw.jsdarf nur Anwendungsdateien, niemals ausgewählte Bilddateien, vorab cachen. Auch Cache-Persistenz und präfixgebundene Bereinigung prüfen. - Produktionsumgebung prüfen: Reverse-Proxy-Konfiguration, Zugriffsprotokolle, TLS, Firewall, Backups, Benutzerrechte und Anbietervereinbarungen separat dokumentieren.
- Regressionstests ausführen:
npm testundnpm run test:e2eprüfen Kernfunktionen, Sicherheitsgrenzen und den Browserablauf.
server.mjs
stats-store.mjs
public/app.mjs
public/converter-core.mjs
public/sw.js
test/
scripts/e2e.mjs
Dokumentationsstand: September 2026 · Technische Beschreibung Version 1.2