Files
Balance/docs/SECURITY.md
T
wt da9e17f45f
Android CI / Build and Test (push) Failing after 13m25s
iOS CI / Build and Test SwiftUI App (push) Canceled after 0s
Build Unsigned iOS and macOS Apps / Build Unsigned iOS IPA (push) Canceled after 0s
Build Unsigned iOS and macOS Apps / Build macOS ZIP (push) Canceled after 0s
added AGENTS.md and docs in root dir
2026-09-08 13:36:43 +07:00

4.9 KiB

Безопасность (сквозные требования)

Этот документ собирает требования безопасности, которые применяются ко всем подпроектам одновременно. Платформенно-специфичные детали — в BalanceServer/docs/SECURITY.md, Balance/AGENTS.md (раздел «Безопасность») и BalanceAndroid/AGENTS.md (раздел «Security»).

Хранение секретов на клиентах

Apple Android
Access/refresh токены Keychain (service BalanceServer) зашифрованное хранилище через Android Keystore (AES/GCM), SecureSessionStore
Несекретные настройки (URL сервера, cursor, sync metadata) UserDefaults ServerPreferences
Запрещено пароль в UserDefaults, SwiftData или файлах токены в обычных SharedPreferences

Ни один клиент не должен хранить пароль пользователя после аутентификации — только access/refresh токены.

Хранение секретов на сервере

  • Пароли — только Argon2id-хеши, plaintext никогда не сохраняется.
  • Refresh-токены хранятся как SHA-256 хеши, не в открытом виде.
  • BALANCE_JWT_SECRET должен быть случайной строкой не короче 32 символов; его смена инвалидирует access-токены (refresh-сессии остаются валидны и получают новый access-токен при следующем refresh).

Транспорт

  • Для удалённого (не-localhost) сервера все клиенты обязаны использовать HTTPS.
  • HTTP разрешён клиентам только для localhost, 127.0.0.1 и ::1 — это относится и к Apple-, и к Android-клиенту.
  • Production-деплой сервера должен работать через HTTPS/TLS (например, через reverse proxy — Caddy/nginx), см. BalanceServer/README.md#https.

Логирование

Запрещено логировать на любой из трёх платформ:

  • пароли;
  • access/refresh токены;
  • заголовок Authorization целиком;
  • полные request bodies с финансовыми данными без явной необходимости.

Безопасно логировать (на сервере): request ID, endpoint, status code, latency, размер batch, неконфиденциальные идентификаторы записей.

Авторизация на сервере

Каждая sync-мутация обязана проверять ownership по authenticated user из токена/сессии. Никогда не доверяй userId, пришедшему в теле запроса от клиента, если identity уже известна из Authorization-заголовка или cookie-сессии:

Authorization header / session cookie
        ↓
   authenticated user
        ↓
   server-side ownership check
        ↓
   requested entity

Валидация входных данных (сервер)

Проверяются: UUID/ID, enum-значения, amount, timestamps, длины строк, размер batch, размер JSON, границы cursor/sequence.

Защита от злоупотреблений (production-деплой сервера)

  • rate limiting для auth-эндпоинтов (встроенный лимитер — 30 auth-запросов на IP в минуту; для более сильного публичного rate limiting используйте reverse proxy);
  • разумные ограничения на размер тела запроса;
  • таймауты и graceful shutdown;
  • ограничение подключений к БД;
  • мониторинг.

Секреты в репозитории

Ни в одном из трёх подпроектов не должны появляться:

  • production URL серверов;
  • реальные BALANCE_JWT_SECRET или иные секреты;
  • закоммиченные .env, keystore-файлы, сертификаты;
  • захардкоженные тестовые credentials, которые могут быть спутаны с боевыми.

.env.example в BalanceServer/ и local.properties.example в BalanceAndroid/ — единственные допустимые «примерные» файлы с конфигурацией; реальные значения в них не хранятся.