Files
2026-09-04 19:50:29 +02:00

179 lines
6.4 KiB
Markdown

# 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
---
## 3. Freigabelinks im Nachrichtentext
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:
```js
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