Bedrohungsmodell & OWASP ASVS L1 Self-Attestation
Die Bedrohungen, gegen die Vaulted ausgelegt ist, die, gegen die nicht, und eine kontrollweise Attestierung gegenüber einer Branchen-Baseline.
Version 1.0 · Veröffentlicht am 2026-04-27 · Quelle: main · Autor: Maxim Novak
Über dieses Dokument
Dies ist eine Self-Attestation, kein Drittanbieter-Audit. Es existiert, damit du genau sehen kannst, was Vaulted zu schützen behauptet, was nicht, und wie jede Design-Entscheidung auf anerkannte Kontrollen abbildet. Wir werden eine unabhängige Überprüfung beauftragen und deren Bericht neben dieser Seite veröffentlichen, sobald das Budget es erlaubt. Bis dahin kannst du die zentrale Zero-Knowledge-Behauptung selbst verifizieren — in fünf Minuten mit den Browser-DevTools.
1. Umfang & Annahmen
Dieses Modell umfasst den Produktions-Deployment von vaulted.fyi einschließlich seines Web-Frontends, API-Routen und Upstash Redis-Speicherung. Es umfasst auch das veröffentlichte CLI und den MCP-Server, soweit sie mit derselben API interagieren.
Außerhalb des Umfangs:
- Das Endgerät des Nutzers (Browser, OS, Erweiterungen, Zwischenablage, Bildschirm).
- Der Kommunikationskanal, über den der Freigabe-Link zugestellt wird (E-Mail, Slack, SMS usw.).
- Der anschließende Umgang des Empfängers mit dem Klartext.
- Schwachstellen in Vercel oder Upstash unterhalb der API-Oberfläche, die wir nutzen.
2. Assets & Vertrauensgrenzen
Primäres Asset: das Geheimnis im Klartext. Es darf den Server nie erreichen, außerhalb der Browser von Absender und Empfänger nie persistieren und allein aus dem serverseitigen Zustand nie wiederherstellbar sein.
Sekundäre Assets: Geheimtext, IVs, Aufrufzähler, Ablauf-Zeitstempel sowie die Integrität und Verfügbarkeit des Dienstes.
Vertrauensgrenzen (in absteigender Vertrauensreihenfolge):
- Browser des Absenders — vertrauenswürdig mit Klartext und Schlüssel.
- Browser des Empfängers — nach dem Öffnen des Links vertrauenswürdig mit Klartext und Schlüssel.
- Netzwerk zwischen Client und Server — nicht vertrauenswürdig; gemildert durch TLS 1.3 und die Design-Entscheidung, dass nur Geheimtext ihn überquert.
- Vaulted-Server (wir) — bedingt vertrauenswürdig. Wird als passiver Geheimtext-Speicher behandelt. Das Bedrohungsmodell geht davon aus, dass Vaulted selbst kompromittiert werden könnte, ohne Klartext preiszugeben.
- Upstash Redis — gleiche Vertrauensstufe wie der Server. Nur verschlüsselte Blobs.
3. Bedrohungsakteure
Passiver Netzwerkbeobachter. ISP, On-Path-Akteur mit Zugriff auf TLS-Metadaten. Wird durch TLS und das Fehlen von Klartext oder Schlüssel im Übertragungsweg abgewehrt.
Aktiver Netzwerkangreifer. Kann einen MitM-Angriff versuchen. Wird durch TLS, HSTS Preload und Zertifikatsvalidierung abgewehrt. Eine erfolgreiche TLS-Kompromittierung liefert trotzdem nur Geheimtext.
Kompromittierter Server / feindlicher Betreiber. Schließt uns ein. Kann gespeicherte Geheimnisse nicht lesen, weil der Schlüssel nie ankommt. Kann den Dienst verweigern oder das ausgelieferte JS-Bundle modifizieren — in den Restrisiken weiter unten behandelt.
Nicht authentifizierter Angreifer mit einem gültigen Freigabe-Link. Per Design kann jeder mit dem vollständigen Link entschlüsseln. Aufruflimits, Ablauf und optionale Passphrase reduzieren das Zeitfenster. Das ist eine bewusste Eigenschaft, kein Bug.
Gezielter Angreifer gegen einen bestimmten Absender oder Empfänger. Kann das Endgerät, den Zustellkanal oder den Umgang des Empfängers nach der Entschlüsselung ausnutzen. Außerhalb von Vaulteds Kontrolle; aus Transparenzgründen dokumentiert.
4. Kontrollen
- Clientseitige AES-256-GCM-Verschlüsselung mit zufälligen 96-Bit-IVs aus
crypto.getRandomValues. - 256-Bit-Schlüssel pro Geheimnis generiert via
crypto.subtle.generateKey; im URL-Fragment platziert, nie übertragen. - Optionales Passphrase-Wrapping mit PBKDF2 (hohe Iterationszahl) und AES-GCM Key Wrapping.
- Atomare Aufrufzähler-Durchsetzung via Redis
HINCRBYmit Löschung in derselben Transaktion beim Erreichen des Limits. - TTL-basierter automatischer Ablauf, auf 30 Tage begrenzt; keine Verlängerung nach der Erstellung.
- Pro-IP Sliding-Window Rate Limiting auf Create- und View-Endpunkten.
noindexauf /s/[id]-Ansichtsseiten, damit Geheimnis-URLs nicht über Suchanfragen durchsickern.- TLS 1.3 mit HSTS Preload, sichere Security-Header, kein IP-Logging über Rate-Limit-Fenster hinaus.
5. Restrisiken (nicht abgewehrt)
Das sind bewusste Grenzenentscheidungen, dokumentiert damit Nutzer entscheiden können, ob Vaulted zu ihrem Bedrohungsmodell passt.
- Kompromittierung des Endgeräts. Ein Keylogger, infizierter Browser oder eine feindliche Erweiterung kann Klartext nach der Entschlüsselung lesen.
- Leck im Zustellkanal. Wird der Freigabe-Link weitergeleitet, archiviert oder in einem antwortenden E-Mail-Thread zitiert, wird dieser Kanal zur Angriffsfläche.
- Gezielter Bundle-Swap. Ein kompromittiertes CDN oder ein Vercel-Edge könnte einem bestimmten Nutzer ein anderes JS ausliefern. Subresource Integrity und reproduzierbare Builds sind partielle Gegenmaßnahmen und stehen auf der Roadmap.
- Verhalten des Empfängers. Nach der Entschlüsselung kann der Empfänger kopieren, einen Screenshot machen oder weiterleiten.
- Schwache Passphrase. Wird eine schwache Passphrase verwendet, ist sie durch jeden mit dem gekapselten Schlüssel per Brute-Force angreifbar.
- Nötigung / Zwang. Außerhalb des Umfangs jeder technischen Kontrolle.
6. OWASP ASVS L1 Self-Attestation
Die folgende Matrix bildet Vaulteds Implementierung auf ausgewählte OWASP ASVS Level 1-Anforderungen ab. Kategorien, die nicht zutreffen (Sessions, Authentifizierung, Datei-Upload), sind mit N/A und einer kurzen Begründung markiert statt weggelassen — damit das Fehlen eines Eintrags nicht als Ausweichen interpretiert wird.
| ID | Kategorie | Anforderung | Status | Nachweis |
|---|---|---|---|---|
| V1.1.1 | Architektur | Sicherer SDLC mit Bedrohungsmodellierung für die Anwendung | Pass | Dieses Dokument. Wird bei jeder wesentlichen Architekturänderung überprüft. |
| V1.4.1 | Architektur | Vertrauenswürdige Durchsetzungspunkte erzwingen Zugriffskontrollen | Pass | API-Route-Handler validieren Eingaben und konsumieren Views atomar via Redis HINCRBY in src/lib/redis-secrets-store.ts. |
| V2.10.x | Authentifizierung | Dienst- / Nutzer-Authentifizierung | N/A | Vaulted ist anonym. Keine Nutzerkonten, keine Dienst-zu-Dienst-Authentifizierung. Die Autorisierung erfolgt über Kenntnis der Geheimnis-ID und des URL-Fragment-Schlüssels. |
| V3.x | Session-Management | Anforderungen an das Session-Management | N/A | Keine Sessions, keine Cookies für authentifizierten Zustand. |
| V5.1.3 | Eingabevalidierung | Eingabevalidierung auf der vertrauenswürdigen Dienstschicht | Pass | Manuelle Laufzeitvalidierung in src/app/api/secrets/route.ts. Payload ≤ 1000 Zeichen serverseitig erzwungen; maximale Views und TTL begrenzt. |
| V5.2.5 | Sanitierung | Ausgabe-Encoding nach Kontext (HTML, JS, URL) | Pass | React escaped standardmäßig alle interpolierten Werte. Die einzigen dangerouslySetInnerHTML-Aufrufe rendern JSON-LD-Literale, die serverseitig aus typisierten Daten konstruiert werden. |
| V6.2.1 | Gespeicherte Kryptografie | Verwendung genehmigter kryptografischer Algorithmen mit sicheren Standardwerten | Pass | AES-256-GCM via Web Crypto API. NIST SP 800-38D. Siehe src/lib/crypto.ts. |
| V6.2.2 | Gespeicherte Kryptografie | Kryptografisch starke Zufallszahlengenerierung | Pass | crypto.getRandomValues für IVs und Schlüsselmaterial. crypto.subtle.generateKey für AES-Schlüssel. |
| V6.2.5 | Gespeicherte Kryptografie | Keine unsicheren oder veralteten kryptografischen Primitiven | Pass | Kein MD5, SHA-1, DES, RC4, ECB oder CBC-ohne-MAC irgendwo im kryptografischen Pfad. |
| V6.3.1 | Gespeicherte Kryptografie | Schlüssel gegen unbefugten Zugriff geschützt | Pass | Der Verschlüsselungsschlüssel erreicht den Server nie. Er lebt nur im URL-Fragment, clientseitig verarbeitet gemäß RFC 3986. Eine optionale Passphrase kapselt den Schlüssel vor dem Teilen mit PBKDF2. |
| V7.1.1 | Fehlerbehandlung & Logging | Keine sensiblen Informationen in Logs | Pass | Der Server loggt nur die Anfrage-Form und Rate-Limit-Entscheidungen. Kein Geheimtext, keine Geheimnis-IDs in einer Weise, die kreuzkorreliert werden könnte, keine über das Rate-Limit-Fenster hinaus persistierten IPs. |
| V7.4.1 | Fehlerbehandlung & Logging | Generische Fehlermeldungen | Pass | API-Routen geben generische HTTP-Status-Codes und kurze Fehler-Strings zurück. Keine Stack-Traces oder interner Zustand nach außen. |
| V8.1.1 | Datenschutz | Sensible Daten identifiziert und geschützt | Pass | Der Server empfängt niemals Klartext. Geheimtext wird in Upstash Redis verschlüsselt gespeichert mit TTL-basierter Löschung und atomarer Aufruflimit-Durchsetzung. |
| V8.3.1 | Datenschutz | Sensible Daten nicht in URLs oder Referrern exponiert | Pass | Der Verschlüsselungsschlüssel lebt im URL-Fragment; Fragmente werden gemäß RFC 3986 §3.5 nie an den Server gesendet und von Browsern aus document.referrer entfernt. |
| V9.1.1 | Kommunikation | TLS für alle Client-Verbindungen | Pass | TLS 1.3 am Vercel-Edge erzwungen. HSTS preloaded. HTTP-Anfragen werden zu HTTPS weitergeleitet. |
| V10.3.2 | Schadcode | Anwendungscode auf Schadcode überprüft | Pass | Ein-Maintainer-Codebase. Alle Commits vom Projektinhaber erstellt; signierte Commits wo unterstützt. Dependency-Updates via Dependabot werden vor dem Merge geprüft. |
| V11.1.1 | Geschäftslogik | Logik-Flows gegen Missbrauch geschützt | Pass | Pro-IP Rate Limiting via Upstash Ratelimit (10 Erstellungen/min, 30 Aufrufe/min). Aufrufzähler atomar dekrementiert. |
| V12.x | Dateien & Ressourcen | Anforderungen an Datei-Upload und -Verarbeitung | N/A | Vaulted akzeptiert keine Datei-Uploads. |
| V13.2.1 | API & Webdienste | RESTful-Endpunkte validieren das Request-Schema | Pass | Alle POST/GET-Handler validieren Pfad-Parameter, Body-Form und Content-Type vor der Verarbeitung. |
| V14.4.3 | Konfiguration | Standard-Security-Header konfiguriert | Pass | HSTS, X-Content-Type-Options, Referrer-Policy und Permissions-Policy via Next.js-Konfiguration gesetzt. Content-Security-Policy per Request in src/proxy.ts mit einem nonce-basierten strict-dynamic script-src erzwungen; API-Routen erhalten eine strenge default-src none-Richtlinie. |
Die Nummerierung folgt der ASVS-4.0-Struktur. Die Liste ist ausgewählt, nicht erschöpfend — das Ziel ist Ehrlichkeit über die Kontrollen, die für einen zustandslosen, kontofreien verschlüsselten Geheimtext-Speicher sinnvoll zutreffen.
7. Änderungsprozess
Jede Änderung, die einen Punkt in diesem Dokument betrifft — neuer Endpunkt, kryptografische Änderung, Dependency-betreffendes Refactoring, Infrastruktur-Änderung — muss eine Überprüfung dieser Seite im selben PR auslösen. Version und Veröffentlichungsdatum oben werden inkrementiert, wenn das Dokument aktualisiert wird; die Vorversion bleibt im öffentlichen Git-Verlauf zugänglich.
Freigabe
Dieses Bedrohungsmodell wird in gutem Glauben vom Maintainer von Vaulted veröffentlicht. Fehler, Auslassungen und Meinungsverschiedenheiten mit den obigen Attestierungen sind ausdrücklich erwünscht — bitte melde sie an [email protected] oder über das Programm zur verantwortungsvollen Offenlegung.
Maxim Novak — Maintainer, vaulted.fyi · 2026-04-27