Model zagrożeń & OWASP ASVS L1 Self-Attestation
Zagrożenia, przed którymi Vaulted jest zaprojektowany, te których nie dotyczy, oraz attestation kontrola po kontroli względem branżowej linii bazowej.
Wersja 1.0 · Opublikowano 2026-04-27 · Źródło: main · Autor: Maxim Novak
O tym dokumencie
To jest self-attestation, nie audyt zewnętrzny. Istnieje po to, abyś mógł/mogła dokładnie zobaczyć, co Vaulted deklaruje chronić, czego nie, i jak każda decyzja projektowa odnosi się do uznanych mechanizmów kontroli. Zlecimy niezależny przegląd i opublikujemy jego raport obok tej strony, gdy pozwoli na to budżet. Do tego czasu możesz samodzielnie zweryfikować kluczowe twierdzenie zero-knowledge w pięć minut z użyciem DevTools przeglądarki.
1. Zakres i założenia
Ten model obejmuje produkcyjny deployment vaulted.fyi włącznie z frontendem webowym, trasami API i przechowywaniem w Upstash Redis. Obejmuje również opublikowane CLI i serwer MCP w zakresie, w jakim wchodzą w interakcję z tym samym API.
Poza zakresem:
- Urządzenie końcowe użytkownika (przeglądarka, system operacyjny, rozszerzenia, schowek, ekran).
- Kanał komunikacji, przez który dostarczany jest link udostępnienia (e-mail, Slack, SMS itp.).
- Późniejsze postępowanie odbiorcy z plaintekstem.
- Podatności w Vercel lub Upstash poniżej powierzchni API, z której korzystamy.
2. Zasoby i granice zaufania
Zasób podstawowy: sekret w postaci plaintekstu. Nie może nigdy dotrzeć do serwera, nie może utrwalić się poza przeglądarkami nadawcy i odbiorcy, ani nie może zostać odtworzony wyłącznie ze stanu po stronie serwera.
Zasoby wtórne: ciphertext, IV, liczniki wyświetleń, znaczniki czasu wygaśnięcia oraz integralność i dostępność serwisu.
Granice zaufania (w kolejności malejącego zaufania):
- Przeglądarka nadawcy — zaufana z plaintekstem i kluczem.
- Przeglądarka odbiorcy — zaufana z plaintekstem i kluczem po otwarciu linku.
- Sieć między klientem a serwerem — niezaufana; łagodzone przez TLS 1.3 i decyzję projektową, że tylko ciphertext ją przekracza.
- Serwer Vaulted (my) — częściowo zaufany. Traktowany jako pasywny magazyn ciphertekstu. Model zagrożeń zakłada, że sam Vaulted mógłby zostać skompromitowany bez ujawniania plaintekstu.
- Upstash Redis — ten sam poziom zaufania co serwer. Wyłącznie zaszyfrowane bloby.
3. Aktorzy zagrożeń
Pasywny obserwator sieci. ISP, aktor on-path z dostępem do metadanych TLS. Pokonywany przez TLS i brak plaintekstu lub klucza w transmisji.
Aktywny atakujący sieciowy. Może próbować ataku MitM. Pokonywany przez TLS, HSTS preload i walidację certyfikatów. Udane skompromitowanie TLS nadal daje wyłącznie ciphertext.
Skompromitowany serwer / wrogi operator. Obejmuje nas. Nie może odczytać przechowywanych sekretów, bo klucz nigdy nie dociera. Może odmówić usługi lub zmodyfikować serwowany bundle JS — opisane w ryzyku rezydualnym poniżej.
Nieuwierzytelniony atakujący z prawidłowym linkiem udostępnienia. Z założenia każdy posiadający pełny link może odszyfrować. Limity wyświetleń, wygaśnięcie i opcjonalna passphrase skracają okno czasowe. To celowa właściwość, nie błąd.
Ukierunkowany atakujący na konkretnego nadawcę lub odbiorcę. Może wykorzystać urządzenie końcowe, kanał dostarczenia lub postępowanie odbiorcy po odszyfrowaniu. Poza kontrolą Vaulted; udokumentowane dla przejrzystości.
4. Mechanizmy kontroli
- Klientskie AES-256-GCM z losowymi 96-bitowymi IV z
crypto.getRandomValues. - 256-bitowe klucze generowane per sekret przez
crypto.subtle.generateKey; umieszczane we fragmencie URL, nigdy nie przesyłane. - Opcjonalne owijanie passphrase z PBKDF2 (wysoka liczba iteracji) i key wrapping AES-GCM.
- Atomowe egzekwowanie licznika wyświetleń przez Redis
HINCRBYz usunięciem w tej samej transakcji przy osiągnięciu limitu. - Automatyczne wygasanie oparte na TTL, ograniczone do 30 dni; brak przedłużenia po utworzeniu.
- Rate limiting per IP ze sliding window na endpointach tworzenia i wyświetlania.
noindexna stronach wyświetlania /s/[id], żeby URL-e sekretów nie wyciekały przez wyszukiwarki.- TLS 1.3 z HSTS preload, bezpieczne nagłówki bezpieczeństwa, brak logowania IP poza oknami rate limitów.
5. Ryzyka rezydualne (bez obrony)
To są celowe decyzje o granicach, udokumentowane po to, by użytkownicy mogli zdecydować, czy Vaulted pasuje do ich modelu zagrożeń.
- Skompromitowanie urządzenia końcowego. Keylogger, zainfekowana przeglądarka lub wrogie rozszerzenie może odczytać plaintext po odszyfrowaniu.
- Wyciek kanału dostarczenia. Jeśli link udostępnienia zostanie przekazany dalej, zarchiwizowany lub zacytowany w wątku e-mail odpowiedzi, ten kanał staje się powierzchnią ataku.
- Celowa podmiana bundla. Skompromitowane CDN lub Vercel edge może serwować inny JS konkretnemu użytkownikowi. Subresource Integrity i odtwarzalne buildy są częściowym środkiem zaradczym i są na roadmapie.
- Zachowanie odbiorcy. Po odszyfrowaniu odbiorca może skopiować, zrobić zrzut ekranu lub przekazać treść dalej.
- Słaba passphrase. Jeśli użyta, słabą passphrase można złamać brute-force przez każdego posiadającego owinięty klucz.
- Wymuszenie / przymus fizyczny. Poza zakresem jakiejkolwiek kontroli technicznej.
6. OWASP ASVS L1 Self-Attestation
Poniższa macierz odnosi implementację Vaulted do wybranych wymagań OWASP ASVS Level 1. Kategorie, które nie mają zastosowania (sesje, uwierzytelnianie, przesyłanie plików), są oznaczone N/A z krótkim uzasadnieniem zamiast pominięcia — by brak wpisu nie był odczytywany jako unikanie.
| ID | Kategoria | Wymaganie | Status | Dowód |
|---|---|---|---|---|
| V1.1.1 | Architektura | Bezpieczny SDLC z modelowaniem zagrożeń dla aplikacji | Pass | Ten dokument. Przeglądany przy każdej istotnej zmianie architektury. |
| V1.4.1 | Architektura | Zaufane punkty egzekwowania wymuszają kontrolę dostępu | Pass | Handlery tras API walidują wejście i konsumują widoki atomowo przez Redis HINCRBY w src/lib/redis-secrets-store.ts. |
| V2.10.x | Uwierzytelnianie | Uwierzytelnianie usługi / użytkownika | N/A | Vaulted jest anonimowy. Brak kont użytkowników, brak uwierzytelniania usługa-do-usługi. Autoryzacja przez znajomość ID sekretu i klucza fragmentu URL. |
| V3.x | Zarządzanie sesją | Wymagania zarządzania sesją | N/A | Brak sesji, brak cookies dla stanu uwierzytelnienia. |
| V5.1.3 | Walidacja wejścia | Walidacja wejścia na zaufanej warstwie usług | Pass | Ręczna walidacja runtime w src/app/api/secrets/route.ts. Payload ≤ 1000 znaków egzekwowany po stronie serwera; maksymalna liczba widoków i TTL ograniczone. |
| V5.2.5 | Sanityzacja | Kodowanie wyjścia zgodne z kontekstem (HTML, JS, URL) | Pass | React domyślnie escapuje wszystkie interpolowane wartości. Jedyne wywołania dangerouslySetInnerHTML renderują literały JSON-LD konstruowane po stronie serwera z typizowanych danych. |
| V6.2.1 | Przechowywana kryptografia | Używanie zatwierdzonych algorytmów kryptograficznych z bezpiecznymi domyślnymi | Pass | AES-256-GCM przez Web Crypto API. NIST SP 800-38D. Patrz src/lib/crypto.ts. |
| V6.2.2 | Przechowywana kryptografia | Kryptograficznie silne generowanie liczb losowych | Pass | crypto.getRandomValues dla IV i materiału kluczowego. crypto.subtle.generateKey dla kluczy AES. |
| V6.2.5 | Przechowywana kryptografia | Brak niepewnych lub przestarzałych prymitywów kryptograficznych | Pass | Brak MD5, SHA-1, DES, RC4, ECB lub CBC-bez-MAC gdziekolwiek w ścieżce kryptograficznej. |
| V6.3.1 | Przechowywana kryptografia | Klucze chronione przed nieautoryzowanym dostępem | Pass | Klucz szyfrowania nigdy nie dociera do serwera. Istnieje tylko we fragmencie URL, przetwarzany po stronie klienta zgodnie z RFC 3986. Opcjonalna passphrase owija klucz z PBKDF2 przed udostępnieniem. |
| V7.1.1 | Obsługa błędów i logowanie | Brak poufnych informacji w logach | Pass | Serwer loguje tylko kształt żądania i decyzje rate limitów. Brak ciphertekstu, brak ID sekretów w sposób umożliwiający korelację, brak IP utrwalonych poza oknem rate limitu. |
| V7.4.1 | Obsługa błędów i logowanie | Ogólne komunikaty błędów | Pass | Trasy API zwracają ogólne kody statusu HTTP i krótkie ciągi błędów. Brak stack trace'ów ani wewnętrznego stanu na zewnątrz. |
| V8.1.1 | Ochrona danych | Wrażliwe dane zidentyfikowane i chronione | Pass | Serwer nigdy nie odbiera plaintekstu. Ciphertext jest przechowywany zaszyfrowany w Upstash Redis z usuwaniem opartym na TTL i atomowym egzekwowaniem limitu wyświetleń. |
| V8.3.1 | Ochrona danych | Wrażliwe dane nieeksponowane w URL-ach ani referrerach | Pass | Klucz szyfrowania żyje we fragmencie URL; fragmenty nigdy nie są wysyłane do serwera i są usuwane z document.referrer przez przeglądarki zgodnie z RFC 3986 §3.5. |
| V9.1.1 | Komunikacja | TLS dla wszystkich połączeń klientów | Pass | TLS 1.3 egzekwowany na Vercel edge. HSTS preloaded. Żądania HTTP są przekierowywane na HTTPS. |
| V10.3.2 | Złośliwy kod | Kod aplikacji przeglądany pod kątem złośliwego kodu | Pass | Codebase z jednym maintainerem. Wszystkie commity autoryzowane przez właściciela projektu; podpisane commity gdzie obsługiwane. Aktualizacje zależności przez Dependabot przeglądane przed mergem. |
| V11.1.1 | Logika biznesowa | Przepływy logiki chronione przed nadużyciami | Pass | Rate limiting per IP przez Upstash Ratelimit (10 tworzeń/min, 30 widoków/min). Liczniki wyświetleń dekrementowane atomowo. |
| V12.x | Pliki i zasoby | Wymagania przesyłania i przetwarzania plików | N/A | Vaulted nie akceptuje przesyłania plików. |
| V13.2.1 | API i usługi webowe | Endpointy RESTful walidują schemat żądania | Pass | Wszystkie handlery POST/GET walidują parametry ścieżki, kształt body i content-type przed przetwarzaniem. |
| V14.4.3 | Konfiguracja | Skonfigurowane standardowe nagłówki bezpieczeństwa | Pass | HSTS, X-Content-Type-Options, Referrer-Policy i Permissions-Policy ustawione przez konfigurację Next.js. Content-Security-Policy egzekwowany per żądanie w src/proxy.ts z opartym na nonce strict-dynamic script-src; trasy API otrzymują restrykcyjną politykę default-src none. |
Numeracja zgodna ze strukturą ASVS 4.0. Lista jest wybrana, nie wyczerpująca — celem jest szczerość co do mechanizmów kontroli, które mają realne zastosowanie do bezstanowego, bezkontoweego zaszyfrowanego magazynu ciphertekstu.
7. Proces zmian
Każda zmiana wpływająca na element w tym dokumencie — nowy endpoint, zmiana kryptograficzna, refaktoring wpływający na zależności, zmiana infrastruktury — musi wywołać przegląd tej strony w tym samym PR. Wersja i data publikacji powyżej zostaną zaktualizowane przy aktualizacji dokumentu; poprzednia wersja pozostaje dostępna w publicznej historii git.
Zatwierdzenie
Ten model zagrożeń jest publikowany w dobrej wierze przez maintainera Vaulted. Błędy, pominięcia i niezgodności z powyższymi attestacjami są wyraźnie mile widziane — prosimy zgłaszać je na [email protected] lub przez program odpowiedzialnego ujawniania.
Maxim Novak — maintainer, vaulted.fyi · 2026-04-27