Initial commit
This commit is contained in:
178
SICHERHEIT.md
Normal file
178
SICHERHEIT.md
Normal file
@@ -0,0 +1,178 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user