Initial commit

This commit is contained in:
2026-09-04 19:49:43 +02:00
parent 7ce9248e95
commit 30faf00ba2
47 changed files with 3946 additions and 0 deletions

200
SICHERHEIT.md Normal file
View File

@@ -0,0 +1,200 @@
# Sicherheitsbetrachtung
Was die Erweiterung tut, welche Angriffswege sich daraus ergeben und was
dagegen unternommen wird. Stand: Version 1.0.0.
---
## Was die Erweiterung überhaupt macht
| Handlung | Vertrauensgrenze |
|---|---|
| HTTPS-Anfragen an eine konfigurierte Adresse | Gegenstelle ist nicht vertrauenswürdig |
| Dateien herunterladen und im Benutzerprofil ablegen | Inhalt ist nicht vertrauenswürdig |
| Heruntergeladene Dateien in LibreOffice öffnen | **kritischster Schritt** |
| Lokale Dateien hochladen | eigener Inhalt |
| Token dauerhaft speichern | Geheimnis |
Der gefährlichste Schritt ist das Öffnen. Alles andere ist Datenverkehr.
---
## 1. Codeeinschleusung über Dokumente
**Die ernsteste Gefahr.** Ein ODT oder DOCX kann Makros enthalten, die
beim Öffnen ausgeführt werden. Und ein Dokument aus dem Archiv ist fremder
Inhalt — auch aus dem eigenen Bestand, denn dort landen Dateien aus
E-Mail-Anhängen, Scannerordnern und Netzfreigaben.
Ohne Gegenmaßnahme wäre die Erweiterung ein bequemer Weg, ein präpariertes
Dokument ins Archiv zu legen und darauf zu warten, dass es jemand öffnet.
**Maßnahme.** Beim Laden werden zwei Einstellungen erzwungen:
```python
MACRO_NEVER_EXECUTE = 1 # com.sun.star.document.MacroExecMode
UPDATE_NO_UPDATE = 0 # com.sun.star.document.UpdateDocMode
doc = desktop.loadComponentFromURL(
url, "_blank", 0,
(prop("ReadOnly", readonly),
prop("MacroExecutionMode", MACRO_NEVER_EXECUTE),
prop("UpdateDocMode", UPDATE_NO_UPDATE)))
```
`NEVER_EXECUTE` bedeutet: Makros werden nicht ausgeführt, **auch nicht nach
Rückfrage**. Der Anwender kann sie nicht aus Versehen freigeben — anders
als bei der gelben Leiste, die LibreOffice sonst anzeigt.
`NO_UPDATE` verhindert das Nachladen verknüpfter Inhalte. Sonst könnte ein
Dokument beim Öffnen eine Adresse abrufen und damit bestätigen, dass es
geöffnet wurde, oder Inhalte aus dem lokalen Netz einbinden.
**Restrisiko.** Sicherheitslücken im Parser von LibreOffice selbst deckt
das nicht ab. Ein präpariertes Dokument, das einen Speicherfehler auslöst,
wirkt unabhängig von diesen Einstellungen. Dagegen hilft nur, LibreOffice
aktuell zu halten.
---
## 2. Pfadmanipulation über Dateinamen
Der Dateiname beim Herunterladen stammt aus dem Kopfzeilenfeld
`Content-Disposition` der Gegenstelle. Ein Wert wie `../../.bashrc` oder
`..\..\Autostart\x.lnk` würde beim Ablegen aus dem Arbeitsverzeichnis
herausführen.
**Maßnahme.** Vollständige Bereinigung in `safe_filename()`:
- **beide** Trennzeichen entfernen, nicht nur das der laufenden Plattform —
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`…) mit `_` versehen
- Punkte und Leerzeichen am Ende, die Windows stillschweigend abschneidet
- Länge begrenzen, Endung dabei erhalten
Geprüft mit:
| Eingabe | Ergebnis |
|---|---|
| `../../../etc/passwd` | `passwd` |
| `..\..\Windows\System32\evil.dll` | `evil.dll` |
| `CON` | `_CON` |
| ` .. ` | `Dokument` |
---
## 3. Ablageort
Ein Arbeitsverzeichnis unter `/tmp` wäre auf Mehrbenutzersystemen für alle
beschreibbar. Ein anderer Benutzer könnte dort unter dem erwarteten Namen
einen symbolischen Verweis anlegen und das Schreiben in eine fremde Datei
umlenken — ein klassischer Symlink-Angriff.
**Maßnahme.** Die Dateien liegen unter
`<Benutzerprofil>/paperless-libreoffice/arbeit/`, angelegt mit `0700`.
Einzelne Dateien werden mit `os.open(..., 0o600)` erzeugt, nicht
nachträglich per `chmod` — sonst gäbe es ein Zeitfenster, in dem sie
lesbar wären.
---
## 4. Der Token
Er liegt im Klartext in `settings.json` mit Modus `0600`. Das entspricht
dem, was Desktop-Anwendungen üblicherweise tun, ist aber **kein
Geheimnisspeicher**.
Was dagegen sichergestellt ist:
- Der Token wird nie in eine Fehlermeldung übernommen. Bei HTTP-Fehlern
erscheint die Adresse, nie das Kopfzeilenfeld.
- Er steht nur im Arbeitsspeicher und in der Einstellungsdatei.
- Im Eingabefeld erscheinen Sternchen.
**Wer es strenger will**, müsste die Erweiterung an den Systemschlüssel-
bund anbinden — über `com.sun.star.task.PasswordContainer` oder libsecret.
Das ist nicht umgesetzt.
**Empfehlung:** In Paperless einen eigenen Token für die Erweiterung
anlegen, nicht denselben wie für andere Werkzeuge. Dann lässt er sich
einzeln widerrufen.
---
## 5. Transport
**Adressprüfung.** Nur `http` und `https` werden angenommen. Ohne diese
Prüfung ließe sich `file:///etc/shadow` als Basisadresse hinterlegen, und
`urllib` würde das bedienen — aus einer Adresseingabe würde ein
Dateizugriff.
| Eingabe | Ergebnis |
|---|---|
| `https://dms.example.org` | angenommen |
| `file:///etc/shadow` | abgewiesen |
| `ftp://server/pfad` | abgewiesen |
| `dms.example.org` (ohne Schema) | abgewiesen |
**Weiterleitungen.** Der Vorgabe-Handler von `urllib` erlaubt auch `ftp`.
Ein eigener Handler weist alles außer `http` und `https` ab — eine
übernommene Gegenstelle kann so nicht auf ein anderes Protokoll umlenken.
**Zertifikatsprüfung.** Standardmäßig aktiv. Sie lässt sich für
Testinstanzen abschalten; im Dialog steht dann der Hinweis, dass die
Verbindung ohne Prüfung angreifbar ist.
**Größenbegrenzung.** 32 MB für Metadaten, 512 MB für Dateien. Ohne
Begrenzung könnte eine fehlerhafte oder böswillige Gegenstelle mit einer
endlosen Antwort den Arbeitsspeicher füllen.
---
## 6. Was an Paperless geschickt wird
Alle Anfragen laufen über die REST-Schnittstelle mit JSON- oder
Multipart-Kodierung. Es werden keine Zeichenketten in Abfragen
zusammengesetzt, es gibt also keine Einschleusung auf dieser Ebene.
Der Suchbegriff wird über `urlencode` kodiert. Titel, Tagnamen und
Zusatzfelder gehen als JSON — die Kodierung übernimmt `json.dumps`.
Die Erweiterung kann in Paperless nur das, was der hinterlegte Token darf.
Wer die Rechte begrenzen will, legt in Paperless einen Benutzer mit
eingeschränkten Objektrechten an und erzeugt dessen Token.
---
## 7. Was die Erweiterung NICHT tut
- keine Ausführung von Code aus Antworten der Gegenstelle
- kein `eval`, kein `exec`, kein `pickle`
- kein Starten externer Programme
- kein Schreiben außerhalb des eigenen Arbeitsverzeichnisses
- keine Übertragung an Dritte; einzige Gegenstelle ist die konfigurierte
Adresse
---
## 8. Bekannte Grenzen
| Punkt | Bewertung |
|---|---|
| Token im Klartext in einer Datei | üblich, aber nicht ideal |
| Parser-Lücken in LibreOffice | nicht abdeckbar, aktuell halten |
| Kompromittierte Paperless-Instanz | liefert Dateien; Makros bleiben gesperrt, Parser-Lücken bleiben |
| Kein Schutz gegen einen Angreifer mit Zugriff auf das eigene Benutzerkonto | systembedingt |
| `chmod` unter Windows weitgehend wirkungslos | dort greift die Zugriffssteuerung des Benutzerprofils |
---
## Empfehlungen für den Betrieb
1. Eigenen Token für die Erweiterung, einzeln widerrufbar
2. Zertifikatsprüfung eingeschaltet lassen
3. LibreOffice aktuell halten — dort liegt das verbleibende Risiko
4. Paperless nie ohne Reverse Proxy mit TLS aus dem Internet erreichbar
machen
5. In Paperless Zwei-Faktor für die Weboberfläche aktivieren; der Token
umgeht das für die Schnittstelle, deshalb Punkt 1