179 lines
6.4 KiB
Markdown
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
|