Files
thunderbird-paperless-conne…/SICHERHEIT.md
2026-09-04 19:50:29 +02:00

6.4 KiB

Sicherheitsbetrachtung

Was die Erweiterung tut, welche Angriffswege sich daraus ergeben und was dagegen unternommen wird. Stand: Version 1.5.0.


Ausgangslage

Die Lage ist deutlich entspannter als bei der LibreOffice-Fassung. Dort war der kritischste Schritt das Öffnen eines heruntergeladenen Dokuments in einer Anwendung mit Makrofähigkeit. Das entfällt hier vollständig — die Erweiterung öffnet nichts, sie überträgt nur.

Handlung Vertrauensgrenze
HTTPS-Anfragen an die konfigurierte Adresse Gegenstelle nicht vertrauenswürdig
Anhänge und Nachrichten hochladen Inhalt vom Absender, nicht vertrauenswürdig
Dokumente als Anhang in Entwürfe Inhalt aus dem Archiv
Freigabelink in den Nachrichtentext erzeugte Zeichenkette
Token dauerhaft speichern Geheimnis

1. Berechtigungen

Bewusst knapp gehalten:

Recht Wofür Anmerkung
storage Einstellungen
menus Kontextmenüs
messagesRead Anhänge und .eml lesen nur auf Anforderung genutzt
compose Anhang und Link einfügen
notifications Fehlermeldungen

compose.send wurde entfernt. Es stand im ersten Entwurf, ohne je benutzt zu werden — die Erweiterung verschickt nichts. Ein Recht, das nicht gebraucht wird, gehört nicht ins Manifest.

Kein pauschales Zugriffsrecht auf Adressen. Statt host_permissions steht dort optional_host_permissions, und beim Speichern der Einstellungen wird das Recht für genau die eingetragene Adresse erbeten. Der Unterschied ist erheblich: Eine Erweiterung mit <all_urls> darf jede Adresse erreichen. Hier ist es genau ein Ursprung, und der Anwender sieht beim Erteilen, welcher.

Die Abfrage muss aus einer Benutzeraktion heraus erfolgen und steht deshalb als erste Anweisung im Klickhandler — vor jedem await. Nach dem ersten await gilt der Aufruf nicht mehr als aus einer Benutzeraktion stammend, und Thunderbird lehnt ihn ab.


2. Dateinamen aus Anhängen

Der Name eines Anhangs stammt vom Absender und ist damit nicht vertrauenswürdig. Er wird zwar nur an Paperless weitergereicht und nicht ins Dateisystem geschrieben, aber ein Wert wie ../../x hat in einem Dateinamen nichts zu suchen — und was die Gegenstelle damit tut, ist nicht Sache dieser Erweiterung.

sichererName() entfernt:

  • Pfadanteile, beide Trennzeichen — unter Linux ist \ ein gültiges Zeichen im Dateinamen, unter Windows ein Trenner
  • unter Windows verbotene Zeichen und Steuerzeichen
  • reservierte Gerätenamen (CON, AUX, NUL, COM1…)
  • Punkte und Leerzeichen am Ende

Beim Einfügen in eine HTML-Nachricht werden Adresse und Dokumentname maskiert (escapeHtml). Ohne das könnte ein Dokumenttitel mit spitzen Klammern Auszeichnung in den Entwurf einschleusen.

Der Titel stammt aus Paperless und damit mittelbar aus fremden Quellen — wer ein Dokument per Mail ins Archiv einliefern kann, bestimmt dessen Titel mit.


4. Nachrichten zwischen Dialog und Ereignisseite

Die Dialoge sprechen nicht selbst mit Paperless, sondern rufen die Ereignisseite. Dort wird der Absender geprüft:

if (absender?.id && absender.id !== browser.runtime.id) {  }

Thunderbird lässt fremde Absender ohnehin nicht durch, solange kein externally_connectable gesetzt ist. Die Prüfung kostet nichts und hält die Zusicherung explizit.

Aufträge werden nach 30 Minuten verworfen. Ein Auftrag enthält Betreff, Absender und Dateinamen; das muss nicht bis zum Neustart im Speicher liegen, nur weil jemand einen Dialog offen stehen liess.


5. Speicherverhalten

Anhangdaten werden erst beim Hochladen geladen, nicht beim Öffnen des Dialogs. Bei einer Nachricht mit mehreren großen Anhängen läge sonst alles im Speicher, während der Anwender noch überlegt.


6. Transport

Adressprüfung. Nur http und https. Ohne diese Prüfung liessen sich andere Schemata hinterlegen, die fetch teilweise bedient.

Keine eigenen Kopfzeileneinträge. Ein selbst gesetzter Eintrag wie X-Client ist nicht CORS-sicher und löst eine Vorabanfrage aus. Antwortet die Gegenstelle darauf nicht wie erwartet, scheitert schon der erste Aufruf mit NetworkError — einer Meldung, die über die Ursache nichts verrät. Das stand im ersten Entwurf und ist entfernt.

Zertifikatsprüfung. Nicht abschaltbar. WebExtensions können das ohnehin nicht umgehen, und das ist richtig so.


7. Der Token

Er liegt im Klartext in browser.storage.local, also im Profil von Thunderbird. Das entspricht dem, was Erweiterungen üblicherweise tun, ist aber kein Geheimnisspeicher.

Was sichergestellt ist:

  • Er erscheint nie in einer Fehlermeldung — bei HTTP-Fehlern werden Adresse und Antworttext gezeigt, nie das Kopfzeilenfeld.
  • Im Eingabefeld erscheinen Punkte (type="password").

Empfehlung: In Paperless einen eigenen Token für diese Erweiterung anlegen. Dann lässt er sich einzeln widerrufen, ohne andere Werkzeuge zu stören. Wer die Rechte begrenzen will, legt einen Benutzer mit eingeschränkten Objektrechten an und erzeugt dessen Token — die Erweiterung kann dann nur, was dieser Benutzer darf.


8. Was die Erweiterung NICHT tut

  • kein eval, kein innerHTML mit fremden Inhalten — alle Listen werden über textContent und createElement aufgebaut
  • kein Öffnen heruntergeladener Dateien
  • kein Schreiben ins Dateisystem
  • kein Versenden von Nachrichten
  • keine Übertragung an Dritte; einzige Gegenstelle ist die konfigurierte Adresse

9. Bekannte Grenzen

Punkt Bewertung
Token im Klartext im Profil üblich für Erweiterungen
messagesRead erlaubt technisch das Lesen aller Nachrichten für die Funktion nötig; genutzt nur auf Anforderung
Kompromittierte Paperless-Instanz könnte manipulierte Dokumente als Anhang liefern — sie werden aber nicht geöffnet, nur angehängt
Kein Schutz gegen Zugriff auf das eigene Benutzerkonto systembedingt
Der Nachrichtentext wird beim Einfügen vollständig neu geschrieben Vorgabe der Compose-Schnittstelle, siehe README

Empfehlungen für den Betrieb

  1. Eigenen Token für die Erweiterung, einzeln widerrufbar
  2. Paperless nur hinter einem Reverse Proxy mit TLS erreichbar machen
  3. Freigabelinks mit Ablauf verwenden, nicht unbegrenzt
  4. Den Tag beim Teilen benutzen — so lässt sich später prüfen, was einmal nach draußen gegeben wurde