Bezpieczeństwo

Bezpieczeństwo bez ściemy

MyFina to domowa księgowość. Dane finansowe są wyjątkowe — pokazujemy, jak są chronione, bez marketingowej waty.

Trzy krótkie odpowiedzi na najważniejsze pytania

Jak jest szyfrowane

TLS 1.3 w transmisji (Let's Encrypt). Zewnętrzne klucze API, tokeny bankowe i sekrety brokerów — AES-256-GCM z unikalnym IV na rekord. Hasła — bcrypt (12 rund). Klucz szyfrujący żyje w env, a nie w bazie.

Gdzie jest przechowywane

PostgreSQL 16 w zarządzanej instancji w Hetzner (Niemcy, UE). Izolowana sieć Docker, brak zewnętrznych połączeń do bazy. Kopie zapasowe — codzienne, szyfrowane przed wysyłką, retencja 30 dni.

Jak jest usuwane

Hard-delete konta w jednym kroku: kaskadowo usuwane są transakcje, konta, kategorie, waluty, tokeny. Bez tabel soft-delete, bez archiwum „na wszelki wypadek”. Leady marketingowe z tego samego e-maila — osobny erase-hook (GDPR Art. 17).

Sześć filarów obrony

Uwierzytelnianie

NextAuth.js v5 na JWT, hasła hashowane bcryptem. Throttling logowania — 5 prób / 15 min na identyfikator i 20 / 15 min na IP. OAuth Google opcjonalnie. Reset hasła — 32-bajtowy token, w bazie tylko jego SHA-256.

Szyfrowanie „at rest”

Zewnętrzne klucze API (banki, Resend, Anthropic) i sekrety brokerów są szyfrowane AES-256-GCM. Klucz nigdy nie opuszcza serwera. Per-connection sekrety webhooków — 32-bajtowe hex dla każdej integracji bankowej.

Izolacja danych użytkownika

Każda operacja UPDATE/DELETE filtruje po `userId`. Ochrona IDOR jest scentralizowana w `assertCanAccessAccount/Category` — próba dostępu do cudzego konta zwraca 403, nie 404. Wspólne konta rodzinne działają na jawnych rolach OWNER/MEMBER/VIEWER.

Sesje i revocation

JWT z inkrementującym się `session_version`. Zmiana hasła, blokada konta lub zmiana roli unieważniają wszystkie aktywne sesje. Refresh-tokeny mobilnego API są rotowane przy każdym odświeżeniu.

GDPR i prywatność

Hard-delete konta usuwa wszystkie transakcje, konta i kategorie kaskadowo w jednej transakcji. Eksport danych — CSV/XLSX/PDF jednym kliknięciem. Cookie consent z dwiema kategoriami (essential / functional), bez analityki i trackerów.

Audyt i obserwowalność

Wszystkie akcje administratora i wrażliwe operacje użytkownika trafiają do `audit_log` z IP, user-agentem i source. Logi prób logowania są przechowywane 30 dni. Zdarzenia webhooków Stripe — osobny dziennik idempotency dla bezpiecznego replay przy awariach.

Czego NIE robimy

  • Nie sprzedajemy ani nie udostępniamy Twoich danych stronom trzecim. Źródłem dochodu jest subskrypcja Pro, nie reklamy.
  • Nie uruchamiamy analityki webowej ani trackerów na stronach użytkowników — brak Google Analytics, Mixpanel, Hotjar.
  • Nie przechowujemy haseł w postaci jawnej — bcrypt z 12 rundami, bez backdoor-recovery.
  • Nie osadzamy Twojego salda ani transakcji na stronach partnerskich — żadnego widgetu, nic do wycieku.

Synchronizacja bankowa — co dokładnie jest przekazywane

Jeśli podłączysz Monobank lub bank PSD2 przez GoCardless, otrzymujemy tylko to, co jest potrzebne do synchronizacji transakcji: płatności wychodzące, przelewy przychodzące, salda kont. Żadnych danych osobowych po stronie banku (paszport, zdjęcie, biometria). Token API banku jest przechowywany zaszyfrowany AES-256-GCM; możesz cofnąć dostęp jednym kliknięciem w Ustawienia → Banki. Zgoda GoCardless wygasa co 90 dni zgodnie z PSD2 — przypominamy 7 dni wcześniej.

Co możesz sprawdzić samodzielnie

Każde stwierdzenie powyżej jest audytowalne w kodzie i API.

  • Szyfrowanie: src/lib/crypto.ts (AES-256-GCM, randomBytes IV, auth tag).
  • Uwierzytelnianie: src/auth.ts, src/lib/auth/rate-limit.ts.
  • Autoryzacja: src/lib/auth/ownership.ts (assertCanAccessAccount).
  • Otwarte API: https://app.my-fina.com/api/openapi (OpenAPI 3.1).
  • Health endpoint: https://app.my-fina.com/api/health (publiczny liveness).

Otrzymuj powiadomienia o bezpieczeństwie

Zapisz się, aby dowiadywać się o CVE, łatkach bezpieczeństwa i zmianach modelu zagrożeń. Bez marketingu.

Powiadom mnie, gdy Pro będzie dostępne

Jeden email. Bez spamu. Wypisanie jednym kliknięciem.

Zgodne z GDPR · dane przetwarzane w UEOstatnia aktualizacja: 3 czerwca 2026