Безопасность

Прозрачно про безопасность

MyFina — домашняя бухгалтерия. Финансовые данные у нас на особом счету: показываем как они защищены без маркетинговой воды.

Три кратких ответа на главные вопросы

Как шифруется

TLS 1.3 в transit (Let's Encrypt). Внешние API-ключи, банковские токены и брокерские секреты — AES-256-GCM с уникальным IV на запись. Пароли — bcrypt (12 раундов). Ключ шифрования живёт в env, не в БД.

Где хранится

PostgreSQL 16 в managed-инстансе в Хетцнере (Германия, ЕС). Изолированный Docker-network, никаких внешних подключений к БД. Бэкапы — ежедневные, шифруются перед загрузкой, retention 30 дней.

Как удаляется

Hard-delete аккаунта в одном кадре: каскадно удаляются транзакции, счета, категории, валюты, токены. Без soft-delete-таблиц, без архива «на всякий случай». Маркетинг-лиды по тому же email — отдельный erase-hook (GDPR Art. 17).

Шесть столпов защиты

Аутентификация

NextAuth.js v5 на JWT, пароль хешируется bcrypt. Логин-троттлинг 5 попыток / 15 мин на identifier и 20 / 15 мин на IP. OAuth Google по выбору. Сброс пароля — 32-байтный токен, в БД только SHA-256.

Шифрование «at rest»

Внешние API-ключи (банки, Resend, Anthropic) и брокерские секреты шифруются AES-256-GCM. Ключ шифрования никогда не покидает сервер. Per-connection webhook-секреты — 32-байт hex для каждой банковской интеграции.

Изоляция данных пользователя

Каждая UPDATE/DELETE-операция фильтруется по `userId`. IDOR-защита централизована в `assertCanAccessAccount/Category` — попытка доступа к чужому счёту даёт 403, не 404. Семейные счета работают через явные роли OWNER/MEMBER/VIEWER.

Сессии и revocation

JWT с инкрементируемым `session_version`. Смена пароля, блокировка пользователя или смена роли инвалидируют все активные сессии. Refresh-токены мобильного API ротируются при каждом обновлении.

GDPR и приватность

Hard-delete аккаунта удаляет все транзакции, счета, категории каскадно в одной транзакции. Экспорт данных — CSV/XLSX/PDF одним кликом. Cookie consent с двумя категориями (essential / functional), без аналитики и трекеров.

Аудит и наблюдаемость

Все админ-действия и чувствительные пользовательские операции пишутся в `audit_log` с IP, user-agent и source. Логи попыток входа хранятся 30 дней. Webhook-события Stripe — отдельный idempotency-журнал для replay при сбоях.

Что мы НЕ делаем

  • Не продаём и не передаём данные третьим лицам. Источник дохода — Pro-подписка, не реклама.
  • Не запускаем веб-аналитику и трекеры на пользовательских страницах — нет Google Analytics, Mixpanel, Hotjar.
  • Не храним пароли в открытом виде — bcrypt с 12 раундами, без backdoor-recovery.
  • Не показываем баланс или транзакции на партнёрских сайтах — никакого embed-виджета, нечего leak'ать.

Банковская синхронизация — что именно передаётся

Если вы подключаете Monobank или PSD2-банк через GoCardless, мы получаем только то, что необходимо для синхронизации транзакций: outbound-payments, входящие переводы, балансы счетов. Никаких персональных данных банка (паспорт, фото, биометрия). API-токен banks хранится зашифрованным AES-256-GCM; вы можете отозвать доступ в один клик из Настроек → Банки. GoCardless-согласие истекает каждые 90 дней по требованию PSD2 — мы напоминаем за 7 дней.

Что вы можете проверить сами

Все утверждения выше — проверяемы по коду и API.

  • Код шифрования: src/lib/crypto.ts (AES-256-GCM, randomBytes IV, auth tag).
  • Аутентификация: src/auth.ts, src/lib/auth/rate-limit.ts.
  • Авторизация: src/lib/auth/ownership.ts (assertCanAccessAccount).
  • Открытый API: https://app.my-fina.com/api/openapi (OpenAPI 3.1).
  • Health endpoint: https://app.my-fina.com/api/health (публичный liveness).

Получать уведомления о безопасности

Подпишитесь, чтобы узнавать о CVE, патчах безопасности и расширениях угроз. Никакого маркетинга.

Сообщить, когда Pro станет доступным

Один email. Никакого спама. Отписаться можно в один клик.

GDPR-compliant · обработка данных в ЕСПоследнее обновление: 3 июня 2026