Wenn Bitwarden plötzlich schweigt: WebAssembly, Vaultwarden 1.37.0 und die Nginx-CSP-Falle
Self-Hosting macht Spaß – bis der Passwort-Manager plötzlich den Dienst verweigert. Bei mir blieb die Bitwarden Browser-Extension kürzlich in einer endlosen Ladeschleife hängen, und im Web-Vault begrüßten mich einzelne Einträge mit der ungemütlichen Meldung [error: cannot decrypt].
Kein Panikmoment, sondern ein perfektes Lehrbeispiel dafür, wie verschachtelt moderne Web-Anwendungen, Docker-Container und Sicherheits-Header miteinander interagieren.
Hier ist die Geschichte der Fehlersuche und wie sich das Problem lückenlos lösen ließ.
Das Fehlerbild: Wenn die Entschlüsselung hakt
Das Symptom war tückisch:
- Der Login am Web-Vault funktionierte problemlos.
- Einzelne Einträge ließen sich öffnen, andere zeigten beim Anklicken nur
[error: cannot decrypt]. - Die Browser-Extension blieb beim Synchronisieren komplett stecken.
Der erste Impuls bei Datenbank-basierten Containern: Ist die SQLite-Datei korrupt? Ein kurzer Check via PRAGMA integrity_check lieferte jedoch ein beruhigendes ok. Auch die Datenstrukturen in der ciphers-Tabelle waren vollkommen intakt.
Die Ursache lag nicht in zerstörten Daten, sondern in zwei aufeinanderfolgenden Versions- und Sicherheits-Barrieren.
Die Ursachenkette: Versionen & WebAssembly
1. Der Client-Server-Mismatch (Vaultwarden 1.36.0 vs. Client 2026+)
Bitwarden hat das Sicherheitskonzept für Tresor-Einträge erweitert (Per-Item Encryption Keys). Neue Client-Apps und Browser-Extensions verschlüsseln Einträge nun mit individuellen Schlüsseln.
Wird der Vaultwarden-Server nicht parallel aktualisiert, versteht der alte Server (v1.36.0) die vom neuen Client geschriebenen Datensätze nicht mehr sauber. Die Folge: Die Extension versucht vergebens, den Eintrag mit veralteten Protokollen zu entschlüsseln, und bricht den Sync-Prozess ab.
Erste Erkenntnis: Der Server musste auf Vaultwarden 1.37.0+ gehoben werden, um die neuen Krypto-Handshakes der Clients zu unterstützen.
2. Der eigentliche Showstopper: Content Security Policy (CSP)
Nach dem Update von Vaultwarden folgte der nächste Überraschungsmoment: Der Web-Vault verharrte in einem dauerhaften Lade-Spinner.
Ein Blick in die Browser-Entwicklerwerkzeuge (F12 → Konsole) förderte den wahren Täter zutage:
Content-Security-Policy: Die Einstellungen der Seite haben die Ausführung eines
WebAssembly (script-src) blockiert, da es gegen folgende Direktive verstößt:
"script-src 'self'"
Was war passiert?
Der neue Web-Vault von Bitwarden nutzt für die clientseitige Entschlüsselung ein performantes WebAssembly (WASM)-Modul (bitwarden_wasm_internal_bg.wasm).
Mein Nginx Proxy Manager lieferte jedoch einen sehr strengen Sicherheits-Header aus: script-src 'self'. Modernes WebAssembly wird von Browsern aus Sicherheitsgründen aber strikt blockiert, wenn die CSP nicht explizit grünes Licht dafür gibt. Das Krypto-Modul konnte nicht geladen werden, die Entschlüsselung schlug fehl.
Die Lösung: Container-Update & CSP-Anpassung
Die Behebung erforderte zwei gezielte Schritte:
Schritt 1: Vaultwarden auf Version 1.37.0+ bringen
Über Portainer bzw. Docker Compose wurde das aktuelle Image gezogen und der Container neu bereitgestellt:
docker compose pull && docker compose up -d
Schritt 2: Reverse Proxy Header anpassen
Im Nginx Proxy Manager musste die Content Security Policy unter den erweiterten Nginx-Einstellungen (Advanced Tab) um die Direktive 'wasm-unsafe-eval' erweitert werden:
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' wss: https:;" always;
💡 Sicherheitshinweis:
'wasm-unsafe-eval'erlaubt zielgerichtet ausschließlich das Ausführen von kompiliertem WebAssembly. Es öffnet nicht die klassische, gefährliche'unsafe-eval'-Lücke für beliebiges JavaScript!
Fazit & Takeaway
Nach dem Leeren des Browser-Caches lief der Tresor sofort wieder blitzschnell.
Was lernen wir daraus für das eigene Homelab?
- Security-Header müssen mitwachsen: Wenn Web-Anwendungen auf neuere Web-Standards wie WASM umstellen, müssen vorgeschaltete Reverse Proxies (Nginx, Traefik, Caddy) angepasst werden.
- Keine voreiligen Datenbank-Eingriffe: Ein
[error: cannot decrypt]bedeutet nicht automatisch, dass Datensätze gelöscht werden müssen. Oft stimmen lediglich die Schlüsselverhandlung oder die Ausführungsrechte im Browser nicht.
🔗 Weiterführende & Nützliche Links
- Vaultwarden GitHub Repository: Offizielle Quellcode-Basis und Release-Notes zu neuen Server-Versionen.
- MDN Web Docs – Content Security Policy (script-src): Ausführliche Dokumentation zur Sicherheits-Direktive und der Spezifikation von
'wasm-unsafe-eval'. - Nginx Proxy Manager Dokumentation: Offizielle Anleitung zur Konfiguration des Proxy-Managers und Custom-Headers.
- Bitwarden Web Vault: Offizielle Seite des Upstream-Projekts Bitwarden.