Безопасность в финтех-проектах: что важно на старте

Почему финтех ломается чаще, чем его взламывают
Когда говорят про безопасность финтех-проекта, в голове сразу всплывает образ хакера: кто-то подбирает пароли, перехватывает трафик, выкачивает базу. Реальность гораздо прозаичнее. Большинство финтех-продуктов в начале своего пути страдают не от целенаправленных атак, а от собственных архитектурных ошибок. Деньги списываются дважды, баланс уходит в минус, один пользователь видит чужие операции, а отчётность не сходится с тем, что реально лежит на счетах. С точки зрения бизнеса последствия те же, что и от взлома: финансовые потери, претензии регулятора и подорванное доверие клиентов.
Корень проблемы в том, что безопасность воспринимается как отдельная фича, которую «прикрутят потом» — после MVP, перед запуском, когда найдётся бюджет на пентест. Но в финтехе безопасность не прикручивается сверху. Она встроена в то, как спроектированы транзакции, как устроена модель доступа и как система ведёт себя в нештатных ситуациях. Если эти решения приняты неправильно на старте, никакой аудит перед релизом их уже не починит — придётся переписывать ядро.
Транзакции: главное место, где теряются деньги
Финтех — это в первую очередь движение денег между счетами. И именно здесь сосредоточена большая часть критических ошибок. Классический сценарий: пользователь нажимает «Оплатить» дважды или мобильное приложение повторяет запрос из-за плохой связи, а сервер обрабатывает его как две отдельные операции. Деньги списываются дважды. Обратный сценарий — гонка двух одновременных запросов на вывод средств, когда оба проверяют баланс «до» списания и оба проходят, уводя счёт в минус.
Защита от этого — не дополнительная функция, а способ проектирования. Каждая денежная операция должна быть идемпотентной: повторный запрос с тем же ключом не создаёт новую транзакцию, а возвращает результат уже выполненной. Балансы и проводки должны меняться внутри одной транзакции базы данных с корректным уровнем изоляции, а не отдельными запросами. И, что критично для аудита, состояние счёта лучше хранить как неизменяемый журнал операций (ledger), из которого баланс вычисляется, а не как одно перезаписываемое поле «остаток».
Частая ошибка: хранить баланс как обычное число в строке пользователя и обновлять его командой «прибавить/вычесть». При любом сбое, дубле или гонке это поле расходится с реальностью, и восстановить, как именно оно туда пришло, уже невозможно. Журнал транзакций (каждая операция — отдельная неизменяемая запись) позволяет в любой момент пересчитать баланс и доказать его регулятору.
Модель доступа: кто и что имеет право делать
Вторая по частоте причина инцидентов — слабая модель доступа. В спешке разработчики проверяют, что пользователь авторизован (аутентификация), но забывают проверить, что именно этому пользователю разрешена конкретная операция над конкретным объектом (авторизация). В результате достаточно подменить идентификатор счёта в запросе, чтобы увидеть или изменить чужие данные. Это называется IDOR и остаётся одной из самых распространённых уязвимостей в финансовых API.
Правильная модель строится на нескольких принципах. Каждый запрос к ресурсу должен проверять не только «кто ты», но и «твой ли это объект». Права должны выдаваться по принципу минимальных привилегий: сотрудник поддержки видит обращения, но не может инициировать выплату; операционист проводит платёж, но не меняет лимиты. Любое привилегированное действие — изменение лимита, ручная корректировка баланса, возврат средств — должно требовать отдельного подтверждения и оставлять неизменяемый след в журнале аудита с указанием, кто, когда и что сделал.
- Разделение ролей — клиент, оператор, администратор, интеграция: у каждого свой набор прав, а не общий «полный доступ».
- Проверка владения на уровне каждого запроса, а не только при входе в систему.
- Принцип четырёх глаз для крупных и необратимых операций: инициирует один, подтверждает другой.
- Журнал аудита, который нельзя отредактировать задним числом и который покрывает все действия с деньгами и настройками.
Данные и секреты: что нельзя хранить как попало
Финтех работает с чувствительными данными: персональные сведения, реквизиты, данные карт. Здесь действует простое правило — то, что вы не храните, у вас невозможно украсть. Полные номера карт хранить нельзя; для этого существуют сертифицированные провайдеры и токенизация. Если вы реально обрабатываете карточные данные, вступает в силу стандарт PCI DSS, и обойти его не получится. Чувствительные данные должны шифроваться и при передаче (TLS повсюду, без исключений), и при хранении.
Отдельная боль начинающих команд — секреты в коде. Ключи доступа к платёжным шлюзам, пароли от баз, токены интеграций попадают в репозиторий, в конфиги, в переписку. Один утёкший ключ к платёжному провайдеру стоит дороже, чем весь остальной проект. Секреты должны жить в защищённом хранилище (vault или менеджер секретов), а не в git, и должны легко ротироваться. В Узбекистане к этому добавляются требования по локализации персональных данных граждан на серверах внутри страны — это нужно закладывать в архитектуру с самого начала, а не переносить базу после запуска.
Важный выбор на старте: брать ли на себя обработку карточных данных или делегировать её лицензированному платёжному оператору и хранить только токены. Для подавляющего большинства продуктов второй путь дешевле, быстрее и снимает огромный пласт требований комплаенса. Самостоятельная обработка карт оправдана только при наличии ресурсов на сертификацию PCI DSS и её ежегодное поддержание.
Что закладывать в архитектуру с первого дня
Есть набор решений, которые почти невозможно добавить задним числом без переписывания системы. Их стоит принять до того, как написана первая строка бизнес-логики. Это идемпотентность операций, журнал транзакций как источник истины, сквозная проверка прав, неизменяемый аудит-лог и продуманная обработка ошибок — система должна корректно вести себя при таймаутах, обрывах связи и частичных сбоях, а не оставлять деньги «зависшими» в неопределённом состоянии.
Не менее важно то, как продукт ведёт себя при сбое платёжного шлюза. Что произойдёт, если провайдер списал деньги, но не вернул вам подтверждение? Если вы не ответили на его вебхук? Эти сценарии — не редкость, а ежедневная норма в проде. Финтех-система должна уметь сверяться с провайдером (reconciliation), повторно запрашивать статус и приводить своё состояние в соответствие с реальным движением денег. Без этого механизма расхождения накапливаются тихо и всплывают в самый неподходящий момент.
Безопасность как фича vs безопасность как фундамент. В первом подходе команда делает MVP «как быстрее», а перед запуском заказывает пентест и латает найденное. Проблема в том, что пентест находит уязвимости в коде, но не чинит дырявую архитектуру транзакций — её придётся переписывать, теряя месяцы. Во втором подходе ключевые решения о транзакциях, доступе и аудите приняты на старте, а пентест уже подтверждает зрелость, а не спасает проект. Второй путь дороже на старте на считаные проценты и кратно дешевле в перспективе.
Регуляторика и человеческий фактор
В Узбекистане финтех работает под надзором Центрального банка и в рамках законодательства о персональных данных и платёжных услугах. Требования к лицензированию, отчётности и хранению данных лучше изучать на этапе проектирования, а не после того, как продукт собрал первых клиентов. Перепроектировать систему под требования регулятора после запуска — самый дорогой способ что-либо менять.
Наконец, значительная часть реальных потерь в финтехе связана не с кодом, а с людьми и процессами: социальная инженерия против сотрудников поддержки, слитые доступы, отсутствие двухфакторной аутентификации у администраторов, единый аккаунт «на всех». Технические меры работают только вместе с дисциплиной: обязательная 2FA для всех привилегированных пользователей, персональные учётные записи вместо общих, регулярный пересмотр прав и понятный план реагирования на инцидент.
Вывод
Безопасность финтех-проекта — это не финальный чек-лист перед релизом, а набор архитектурных решений, принятых на старте: идемпотентные транзакции, журнал операций как источник истины, строгая модель доступа, неизменяемый аудит и продуманная сверка с платёжными провайдерами. Эти вещи невозможно «доделать потом» — их либо закладывают в фундамент, либо потом переписывают ядро ценой месяцев работы и репутации. Если вы планируете финтех-продукт для рынка Узбекистана и хотите, чтобы он выдержал и нагрузку, и проверку регулятора, команда OneDev готова разобрать вашу архитектуру и помочь принять правильные решения до того, как они станут дорогими. Обсудите проект с нами — на старте это всегда дешевле, чем на проде.
Чем безопасность финтеха отличается от безопасности обычного веб-приложения?
Можно ли запустить MVP финтех-продукта без полной безопасности и доделать её позже?
Что такое идемпотентность операций и почему это критично?
Нужно ли нам соответствовать PCI DSS?
Какие требования по данным действуют для финтеха в Узбекистане?
Заменяет ли пентест перед запуском правильную архитектуру?
Нужна похожая система или хотите обсудить проект?
Опишите задачу — предложим архитектуру, технический подход и план работ. Часто для старта достаточно короткого звонка.
Обсудить проект