Keep financial ownership, atomic publication and refresh CAS. Failed refresh leaves cookies untouched; logout still clears them. Remove full-history candle prefetch and special metadata retries. Use native Pino request context instead of parallel middleware. BREAKING CHANGE: remove investment stateVersion, queued sync state, and tbank-sync status progress/resources. Consumers must observe resources through sync=observe with the updated frontend contract.
64 lines
4.5 KiB
Markdown
64 lines
4.5 KiB
Markdown
# Security и auth
|
||
|
||
Читай при изменении session/token/cookie/guard, account access, encryption или
|
||
sensitive logging; обычный data query без этой границы не требует всего документа.
|
||
|
||
## Выбор владельца
|
||
|
||
Identity/session — AuthService + strategy/guard; cookie transport — AuthController;
|
||
account access/connection generation — TbankAccessService; token crypto —
|
||
TbankTokenService/TbankCrypto. Расширяй существующую boundary, не добавляй
|
||
второй JWT middleware, decrypt helper или refresh coordinator.
|
||
|
||
Access проверяется JWT strategy; refresh передаётся httpOnly cookie.
|
||
Сроки token/session принадлежат auth source и configured HTTP tests.
|
||
Source code конфигурации cookie —
|
||
[AuthController](../../src/modules/auth/presentation/auth.controller.ts); изменение flags/path требует
|
||
проверки browser/HTTP поведения, не только TypeScript.
|
||
|
||
Refresh rotation атомарна: один победитель, проигравший/superseded token получает
|
||
401, но не меняет cookie и сам по себе не отзывает session победителя.
|
||
Cookie очищает logout; межвкладочная синхронизация не требуется, допустим re-login.
|
||
Не вводи Web Locks, replay history/grace
|
||
или иной security contract без текущей задачи. Logout идемпотентен, отзывает
|
||
сессию и очищает refresh cookie на HTTP-границе.
|
||
|
||
## Trust boundaries
|
||
|
||
Клиентский интерфейс не является security boundary. DTO runtime validation выполняется
|
||
server-side; whitelist не заменяет access checks. Environment/secret inputs
|
||
проверяет existing config owner; реальные credentials не попадают в fixtures.
|
||
|
||
Verified JWT не доказывает доступ к accountId из URL. Используй user.sub и
|
||
existing account access policy; не доверяй userId/token из клиента как authority.
|
||
Cross-user, invalid/expired/superseded token и concurrent requests — обязательные
|
||
cases для соответствующего изменения.
|
||
|
||
T-Bank credentials остаются server-side и хранятся encrypted. Используй
|
||
existing AES-256-GCM boundary с validated 32-byte key; не печатай plaintext,
|
||
шифротекст, cookie, Authorization или connection generation в logs/errors/API.
|
||
Успешная замена/deletion меняет connection generation и инвалидирует её кэши;
|
||
ошибка сохраняет прежнее подключение. Ключ не ротируется автоматически:
|
||
новый ключ не расшифрует сохранённые credentials. Нужен исходный ключ или
|
||
повторное сохранение token пользователем; сохраняй ключ отдельно от backup БД.
|
||
|
||
Не передавай Prisma User/Session целиком наружу; выбирай public DTO. Пароль
|
||
обрабатывает существующий bcrypt flow. Не копируй требования о нормализации
|
||
или длине из tutorial: сверяй runtime DTO, tests и feature source.
|
||
|
||
Предпочитай Prisma query API. Raw SQL допускается только по конкретной нужде
|
||
с параметризованными значениями; не конкатенируй untrusted input и не передавай
|
||
его в `queryRawUnsafe`/`executeRawUnsafe`. Dynamic identifiers выбирай из
|
||
закрытого server-owned набора. Проверка user ownership сохраняется и в SQL.
|
||
|
||
## Безопасный путь и проверка
|
||
|
||
При неясной ownership/crypto/session семантике прочитай exact source до edits.
|
||
Добавляй проверку на ответственной границе; не скрывай проблему общим catch,
|
||
фиктивным success или log. Logger allowlist/redaction не делает произвольный
|
||
message безопасным.
|
||
|
||
Targeted auth/access/crypto/logging tests + [Testing](testing.md).
|
||
Cookie/guard/HTTP changes требуют configured HTTP proof.
|
||
Schema parity не доказывает отсутствие утечки secret.
|