Как некорректная разработка API может привести к удалению пользователей
В продолжение рассказа об уязвимостях, которые были обнаружены пентестерами УЦСБ и легли в основу кейсов на премии Pentest Award, публикуем разбор следующего реального примера.
Расскажем, как в веб-приложении одной компании была обнаружена связка уязвимостей, позволявшая удалить любого зарегистрированного пользователя из системы.
Первичный анализ
Приложение, которое мы исследовали, было классической системой дистанционного доступа пользователей к ресурсам приложения. Для начала мы проверили функциональность, которая была доступна пользователю без аутентификации. Система позволяла зарегистрироваться по номеру телефона пользователя. Это и стало отправной точкой в анализе приложения.
При попытке зарегистрироваться по номеру телефона мы обнаружили, что после ввода ФИО и номера отправляется запрос на конечную точку /api/v1/users? query=eq (phone_number, string: phoneNumber).
Данная конечная точка проверяла наличие зарегистрированных пользователей с таким же номером телефона.
При запросе случайного номера телефона приложение, в зависимости от наличия пользователя в системе, раскрывало часть атрибутов пользователей и тестовый токен в формате Basic.
Других интересных находок не было, поэтому мы перешли к анализу с правами пользователя.
Собираем вектор
Во время разведки API мы заметили, что приложение использует несколько ручек для доступа к информации об учетной записи пользователя. Наше внимание привлекла эта конечная точка:
В данном случае приложение обращалось по некоторому идентификатору, который был подозрительно похож на те, что мы видели, когда перебирали номера телефонов.
Ведомые этой идей, мы попытались совместить две части пазла и достигнуть возможности получать пользовательские атрибуты. Однако нас ждала неудача:
Приложение проверяло токен, и это не давало спокойно перебирать идентификаторы. Мы решили не отпускать идею и посмотреть, какие версии API могут быть доступны, кроме версии 3. Как оказалось, приложение имеет еще и версию v2, но по стандартному токену оно было уже недоступно.
Однако при запросе с тестовым токеном, который был обнаружен на первом шаге, доступ по-прежнему был.
Мы решили перебрать доступные HTTP-методы для данной ручки.
Результат приятно удивил: данная конечная точка поддерживала метод DELETE. Единственное, что требовалось, — указать instanceId
Его можно было увидеть среди тех, что были получены при переборе телефонных номеров:
В целом, все части картины были уже на руках — нужно было лишь проверить, сможем ли мы действительно удалить учетную запись. У нас была запасная учетная запись для проверки разграничения доступа — именно ее и решили пустить на тест.
Запрос ушел на сервер без проблем и вернул нам вполне корректный ответ.
Для проверки наличия пользователя в системе, мы попробовали повторно обратиться к API для получения данных о пользователе по номеру телефона:
Пользователь был успешно удален:
В результате мы имеем возможность удалить любого пользователя из системы. Единственное, что для этого нужно — это номер телефона пользователя.
Реализация цепочки
Для демонстрации атаки использовались следующие уязвимости:
разглашение тестового токена;
возможность получения идентификатора пользователя по номеру телефона;
доступ к альтернативной версии API по тестовому токену;
доступный метод DELETE у конечной точки /api/v2/users.
Схема цепочки атак:
Данный случай показателен тем, что уязвимости, казалось бы, низкого уровня критичности могут привести к реализации ощутимого бизнес-риска для компании, если их соединить в цепочку.
Извлекаем уроки
Чтобы защитить свое приложение от подобных атак, следует придерживаться следующих практик:
Проводить проверку приложений на предмет следов разработки: тестовые токены, конечные точки API и т.д.
Отключать небезопасные HTTP-методы, такие как DELETE, или разрешать их использование только привилегированным учетным записям.
Избегать предоставления пользователям возможностей получения идентификаторов учетных записей по каким-либо атрибутам, например, по номеру телефона или адресу электронной почты.
Разграничивать доступ на основе JWT-токенов или cookie-файлов, а не на основе идентификаторов.
Автор: Никита Распопов, специалист по анализу защищённости УЦСБ