OWASP Top 10: реальные уязвимости в российских проектах

«Многие воспринимают OWASP Top 10 как абстрактный список для сдачи аудита. Но в российском IT это прямое отражение архитектурных привычек и операционных провалов, повторяющихся в госкорпорациях, финтехе и интернет-сервисах. Причина не в недостатке инструментов, а в логике разработки под 152-ФЗ: мы сначала думаем о конфиденциальности данных, забывая, что кирпич, заложенный в основу для ЦОД ФСТЭК, обернётся уязвимостью уровня приложения.»

A01:2021 — Сбои контроля доступа

Типичный сценарий в крупных интеграционных проектах, это REST API, который проверяет права пользователя, но игнорирует права его организации. Например, в системах электронного документооборота (СЭД) для госзаказчиков часто встречается эндпоинт вида /api/documents/{id}. Разработчики добавляют проверку, что пользователь авторизован, но забывают проверить, принадлежит ли запрашиваемый документ его юридическому лицу или подразделению в рамках единого инстанса. В результате сотрудник одной дочерней компании может получить доступ к внутренним приказам другой, если угадает или переберёт идентификатор.

Проблема усугубляется использованием готовых отечественных СУБД или их «защищённых» сборок. Администраторы полагаются на ролевую модель на уровне базы данных, но само приложение, формирующее SQL-запрос, не добавляет критическое условие WHERE org_id = :current_org_id. Уязвимость обнаруживается не сканерами, а при ручном тестировании бизнес-логики.

A02:2021 — Криптографические сбои

Здесь российская специфика проявляется ярче всего. Требования 152-ФЗ и приказы ФСТЭК делают акцент на использовании сертифицированных средств криптографической защиты информации (СКЗИ). Это приводит к парадоксальной ситуации: для хранения паролей применяется дорогой аппаратный токен или ГОСТ, но сами пароли оказываются в логах приложения в открытом виде из-за отладочных настроек. Стандартный совет «используйте bcrypt» не работает, если внутренние регламенты требуют применения только сертифицированных алгоритмов.

Другая распространённая ошибка — неправильная конфигурация TLS даже в критичных системах. В погоне за поддержкой устаревшего клиентского ПО (например, браузеров на тонких клиентах в госучреждениях) администраторы оставляют активными уязвимые протоколы SSLv3 или слабые шифры. Это сводит на нет всю защищённую инфраструктуру, построенную по требованиям регуляторов.

A03:2021 — Внедрение инъекций

Казалось бы, SQL-инъекции — проблема прошлого. Однако в legacy-системах государственных порталов, написанных на PHP или древних версиях Java, они всё ещё встречаются. Более актуальна для современных стеков инъекция в NoSQL-базы, такие как MongoDB, популярные в некоторых отечественных highload-проектах.

Пример: API, принимающий JSON для фильтрации товаров. Вместо безопасного построения запроса через API драйвера, разработчик конкатенирует строку: db.products.find({ price: { $lt: userInput } }). Злоумышленник может передать в userInput не число, а целый объект типа { "$ne": null }, что кардинально изменит логику запроса и позволит извлечь все данные.

A04:2021 — Небезопасный дизайн

Этот пункт — о фундаментальных просчётах на уровне проектирования. Классический пример из российского финтеха — механизм многофакторной аутентификации (2FA). Система требует подтверждения через SMS или push-уведомление, но не лимитирует количество попыток ввода кода на этапе верификации. Злоумышленник, перехвативший логин и пароль (например, через фишинг), может простым перебором подобрать 4-6 значный цифровой код, потому что дизайн системы не предусматривает блокировки после 5-10 неудачных попыток.

Другой аспект — отсутствие контроля за потоком бизнес-операций. В системах онлайн-банкинга иногда можно выполнить операцию «перевод средств», минуя обязательный этап «подтверждения номера карты получателя», если вызывать внутренние API напрямую, что становится возможным из-за неверно спроектированной последовательности вызовов.

A05:2021 — Сбои конфигурации безопасности

Типичная история при развёртывании в «защищённом» контуре: для упрощения администрирования на серверах приложений остаются открытыми порты управления (например, 8080, 9990) или интерфейсы вроде JMX. Доступ к ним ошибочно разрешён не только с localhost, а со всей внутренней сети, что нарушает принцип минимальных привилегий. В случае компрометации одного сервиса злоумышленник получает точку опоры для атаки на всю инфраструктуру.

Частая ошибка — хранение конфигурационных файлов с паролями и ключами доступа прямо в репозитории кода проекта. Это особенно критично, если репозиторий внутренний, но доступ к нему есть у всех разработчиков, включая стажёров. Утечка таких данных сводит на нет изоляцию контуров.

A06:2021 — Уязвимые и устаревшие компоненты

Отечественные проекты, особенно в госсекторе, страдают от двух крайностей. Первая — использование сверхстарых, но «проверенных» библиотек с известными уязвимостями (например, Apache Commons Collections для десериализации в Java-проектах). Обновить их нельзя, потому что это сломает совместимость с другими частями монолита.

Вторая — слепое доверие к сторонним «отечественным» библиотекам или фреймворкам с закрытым исходным кодом, которые позиционируются как безопасные и сертифицированные. Их состав зависимостей (dependencies) часто не анализируется. В результате в стек попадает уязвимая версия Log4j или другой библиотеки, о чём команда узнаёт только после внешнего аудита или инцидента.

A07:2021 — Сбои идентификации и аутентификации

Проблемы часто возникают в механизмах восстановления доступа. Например, в корпоративных порталах функция «Забыли пароль?» позволяет установить новый пароль, ответив на «секретный вопрос». Эти вопросы часто стандартны («Девичья фамилия матери?», «Любимая книга») и ответы на них легко найти в открытых источниках или соцсетях.

Другой пример — неверная реализация сессий. После выхода пользователя (logout) его сессионный токен не инвалидируется на сервере. Если злоумышленник перехватил этот токен (например, через XSS), он сможет использовать его для доступа даже после того, как законный пользователь вышел из системы.

A08:2021 — Сбои обработки данных и сериализации

В микросервисных архитектурах, популярных в крупных российских IT-компаниях, распространён обмен данными в формате JSON или через бинарные протоколы вроде Protocol Buffers. Уязвимость возникает, когда на десериализацию данных не накладываются строгие ограничения по типам и структуре.

Атака на цепочку микросервисов: первый сервис валидирует входящие данные, но затем сериализует их и отправляет второму. Второй сервис, доверяя внутреннему источнику, без проверок десериализует объект. Если злоумышленник скомпрометировал первый сервис или нашёл способ отправить ему сформированные данные, он может внедрить вредоносный объект, который при десериализации во втором сервисе выполнит произвольный код.

A09:2021 — Сбои контроля доступа к API

С развитием API-first подходов эта уязвимость становится критичной. Рассмотрим API для управления облачными ресурсами в отечественном IaaS-провайдере. Есть метод POST /api/v1/servers/{id}/stop для остановки виртуальной машины. API проверяет, что у пользователя есть право на управление ВМ, но не проверяет контекст — находится ли эта ВМ в том же проекте или аккаунте, к которому привязан пользователь. В итоге, зная ID чужой машины (а они часто предсказуемы или перечисляемы), можно вызвать остановку, нарушив доступность чужого сервиса.

Особенно опасны GraphQL API, где один запрос может затрагивать множество сущностей. Без корректно настроенных максимальных глубин вложенности (depth limiting) и проверок прав на каждый уровень злоумышленник может одним сложным запросом выгрузить непредусмотренный объём данных.

A10:2021 — Недостатки журналирования и мониторинга

По требованиям регуляторов, системы обязаны вести детальные логи. Но их полезность для безопасности часто нулевая. Логи заполняются техническими сообщениями вроде «Пользователь подключился», но не содержат ключевых данных для расследования: исходного IP-адреса за прокси, идентификатора сессии, ключевых параметров запроса при попытке инъекции.

Хуже того, в логи часто попадают чувствительные данные: полные номера карт, паспортные данные, сессионные куки. Это создаёт новый вектор для атаки: получив доступ к файлам логов (через уязвимость в другом сервисе или ошибку прав доступа), злоумышленник получает массу персональных данных, которые система должна была защищать. Отсутствие агрегации и корреляции событий из разных источников (приложение, СУБД, сетевой экран) делает обнаружение сложных атак практически невозможным.

Что делать: смещение фокуса

Борьба с OWASP Top 10 в российских реалиях, это не только про внедрение сканеров и статического анализа. Это про изменение процессов.

  • Threat Modeling на старте: Перед разработкой новой фичи или интеграции проводить сессию по поиску угроз. Не абстрактно, а в привязке к конкретным компонентам: «Как можно обойти контроль доступа в этом новом API?», «Куда попадёт этот токен в логах?».
  • Автоматизация проверок в CI/CD: Интеграция инструментов SAST и DAST не как формальность для отчёта, а как обязательный этап, блокирующий сборку при обнаружении критичных уязвимостей. Особое внимание — анализу зависимостей (SCA).
  • Регулярные тесты на проникновение (PenTest) «снаружи» и «изнутри»: Внешний тест имитирует атакующего из интернета. Внутренний — злоумышленника, который уже преодолел периметр (например, сотрудника или взломанную рабочую станцию). Это выявляет проблемы контроля доступа и перемещения внутри сети.
  • Культура безопасного дизайна: Перестать думать о безопасности как о слое, который можно добавить в конце. Требования к безопасности должны быть частью ТЗ на функционал с самого начала, особенно для проектов, попадающих под 152-ФЗ и приказы ФСТЭК.

Игнорирование OWASP Top 10 под предлогом «у нас защищённый периметр и ФСТЭК» — прямая дорога к инцидентам, где утечка данных или остановка сервиса произойдёт не из-за внешнего взлома, а из-за элементарной ошибки в коде, которую можно было предвидеть и устранить на этапе разработки.

Оставьте комментарий