Обновлено: Как я обнаружил проблемы у ЮМани (Сбербанк) с безопасностью и не получил денег за найденную уязвимость

в 6:49, , рубрики: CORS, yoomoney, безопасность, Сбер, Сбербанк, утечка, уязвимость, ЮМани, яндекс.деньги

Предисловие

Как известно, в России почти каждая первая финансовая организация позиционирует себя как софтверную IT-компанию, а не просто как "банк" или "платежная система". Сегодня речь пойдет о ЮМани — подразделении Сбера, IT-гиганта всея руси.

До того, как ЮМани стал тем, чем он сейчас является, сервис долгое время существовал как продукт Яндекса под названием Яндекс.Деньги — в те времена у меня был очень приятный опыт взаимодействия с техническим руководством компании, я неоднократно (будучи security researcher'ом) сообщал им об уязвимостях, а они, в свою очередь, оперативно это исправляли, давали обратную связь и вознаграждали за такую работу, аналогично тому, как это делали и зарубежные крупные IT-компании в рамках взаимодействия с white-hat хакерами. Такая вот IT-компания здорового человека. Но с тем, как Сбербанк поглотил Яндекс.Деньги и провёл ребрендинг, проект стал превращаться, скорее, в IT-компанию курильщика: взаимодействовать с представителями проекта в соц. сетях стало практически невозможно, какие-либо данные на страницах о Bug Bounty программах были удалены и даже ни одного email-адреса не оставили в качестве средства связи для сообщения об уязвимостях.

Пару месяцев назад я обнаружил уязвимость в сервисе ЮМани (о ней чуть позже) и сразу же решил сообщить о ней. Однако никаких релевантных этому форм связи, email-адресов и т.д. я не обнаружил — способов безопасно сообщить о такой уязвимости элементарно не было на официальном сайте сервиса. Я попытался связаться с людьми, работающими в ЮМани, однако, опять же, я не получил никакой обратной связи. На этом моменте я, что называется, "забил", в надежде, что ошибку исправят и без меня, ведь не может же такая дырень оставаться незамеченной долго, правда? Спойлер: может.

В один из прекрасных летних вечеров я воспользовался этой платежной системой в очередной раз, ну и, в рамках праздного интереса, решил проверить, "а не исправили ли". Как выяснилось, нет. Не исправили. И вот получается, что уже на протяжении очень продолжительного периода времени (около 2 месяцев) мне известно о критической уязвимости в сервисе, которую исправить можно было бы за 1-2 минуты (буквально). И тут я решаю связаться хоть каким-то способом с кем-то из этой организации. Кое-как откопал контакты HR-менеджера, с которой состоялся диалог:

HR-менеджер поделилась ссылкой на программу для баг-хантеров

HR-менеджер поделилась ссылкой на программу для баг-хантеров

Как можно догадаться из переписки выше, я отправил отчёт об уязвимости в ЮМани через этот очень сомнительный сервис. Но о нём позже. Пока поговорим о самой уязвимости.

Примечание: На момент написания этой статьи уязвимость исправлена, поэтому её публичное раскрытие не несёт угрозы для сервиса и/или его пользователей, а скорее наоброт — дает конкретное представление о масштабах халатности и том, как Сбербанк/ЮМани относится к тем, кто делает за них важную работу по поиску брешей в безопасности.

Уязвимость

Для поддержания сессии пользователя, сервис ЮМани использует Cookie, по которым идентифицирует учетную запись в системе и возвращает соответствующие пользовательские данные. Если мы зайдем на главную страницу сервиса и войдем в учетную запись, то мы окажемся в личном кабинете по адресу yoomoney.ru/main:

Главная страница личного кабинета ЮМани
Главная страница личного кабинета ЮМани

На странице присутствует базовая информация, такая как: последние 4 цифры имеющихся банковских карт, информация о балансе, номер телефона и информация о последних операциях по счету. Ничего особенного. При взаимодействии с интерфейсом, веб-приложение ходит к yoomoney.ru/api, откуда получает всю необходимую информацию. Казалось бы, этот API и будет нашим основным интересом в плане security research. При этом на данном API-эндпоинте корректно настроен CORS, запрещающий браузерам обращаться к API откуда-либо, кроме как с yoomoney.ru.

Прежде чем обратиться к серверу, браузер посылает Preflight-запрос — вызывая через HTTP методом OPTIONS удаленный сервер, запрашивая заголовки CORS. В такой запрос, как правило, включается заголовок Referrer, сообщающий, с какой странички делается запрос, а заголовки ответа выглядят примерно так:

access-control-allow-credentials: true
access-control-allow-origin: https://example.com

В данном примере сервер ответил, что запросы к нему можно делать только с сайта example.com.

Так вот если на /api CORS, конечно же, настроен правильно и отвечает, что обращаться к нему можно только с yoomoney.ru, то на страницах ЮМани /main (главная страница), /settings (настройки) и /cards (информация о картах) — ситуация совсем другая. В заголовке access-control-allow-origin сервис отвечал всегда тем, что присылалось в Referrer.

Например представим, что я поднял страничку privet-ya-luntik.ru и обращаюсь с помощью XHR-запроса в JS-коде этой страницы на yoomoney.ru/main. Мой браузер сделает запрос:

OPTIONS https://yoomoney.ru/main
Referrer: https://privet-ya-luntik.ru

А ЮМани любезно ответит:

access-control-allow-credentials: true
access-control-allow-origin: https://privet-ya-luntik.ru

т.е., позволит мне делать запросы к этим ресурсам на их сервере и получать их содержимое. Более того, запрашиваться эти ресурсы будут от имени авторизованного пользователя, т.к. заголовок access-control-allow-credentials подразумевает, что браузер может передавать оригинальные Cookie от ЮМани с каждым моим запросом.

Но что мы можем там найти? Это же простой интерфейс, а всё загружается с API. Бесполезная какая-то находка, правда? Я тоже так сначала подумал, но нет. Заглянем, например, в код страницы /main:

А вот тут становится сильно интереснее

А вот тут становится сильно интереснее

Как выяснилось, ЮМани встраивает пользовательские данные в изначально отдаваемую пользователю страницу, дабы тот не ждал лишние несколько мгновений, пока данные подгрузятся из API. Все эти данные заботливо упакованы в JS-объект window.__data__, который, в свою очередь, лежит в одном из тэгов <script>. Сразу в глаза бросается наличие в объекте моего номера телефона, адреса эл. почты, текущего баланса. После более тщательного исследования, выяснилось, что в целом из страницы можно вычленить:

  • баланс пользователя;

  • email пользователя;

  • телефон пользователя;

  • статус идентификации;

  • ID аккаунта;

  • ID пользователя;

  • дату регистрации;

  • информацию о привязанных картах;

  • информацию о выпущенных картах;

  • информацию о текущих настройках безопасности;

  • секретный ключ (его можно потом использовать отдельно для действий от имени пользователя);

  • информацию о привязанных аккаунтах (ГосУслуги, ВК, Сбер);

  • историю транзакций с датами, суммами и типами;

Я решил не долго думать и написал свой Proof-of-Concept. Вот что получилось:

Нажимаешь кнопочку на моей сторонней (вообще не имеющем к ЮМани отношения) страничке и всё — все данные аккаунта в платежной системе (да и доступ к нему) у меня в руках.

Мой пример довольно "вегетарианский" — он просто отображает украденные данные. Однако абсолютно ничего не мешает злоумышленнику создать страницу с идентичным JS-кодом, который будет делать запросы к ЮМани, получать оттуда данные, пересылать их на сервер злоумышленника и затем переадресовывать пользователя куда-то дальше. Конечный пользователь даже не узнает о том, что его данные и доступ к аккаунту были украдены.

Примечание: Разумеется, я не публиковал PoC в открытом доступе, доступ к моей страничке был защищен паролем, которым я позднее поделился с самим ЮМани.

Дальнейшее взаимодействие с ЮМани

Как мне и предложила HR, я направил багрепорт через BugBounty.ru — сервис, при использовании которого возникают очень странные ощущения. На самом ресурсе нет никакой вводной информации о том, кому он принадлежит, кем разработан и как поддерживается. Складывалось впечатление, что он написан кем-то на коленке за пачку сока (возможно, так и было, судя по тому, как развивались события дальше). Ну бог с ним. Зарегистрировался, захожу в раздел "Программы", ожидаю увидеть обширный список того, кто предлагает репортить уязвимости через эту платформу.

Вот кто этим пользуется, кхм.

Вот кто этим пользуется, кхм.

Програм всего три штуки: ЮМани, ВКонтакте и какой-то неоплачиваемый "Мой Полк", (что бы это ни было) запущенный самим сервисом BugBounty.ru — сомнительно, но окей. Захожу, пишу и отправляю отчет в начале рабочего дня, 26 августа 2024 года:

Подробное описание уязвимости

Подробное описание уязвимости

Сообщаю об этом той HR, которая изначально выдала мне ссылку на эту платформу. Через несколько минут в отчете появляется комментарий сотрудника:

Обновлено: Как я обнаружил проблемы у ЮМани (Сбербанк) с безопасностью и не получил денег за найденную уязвимость - 6

«Окей» подумал я. Уязвимость критическая, исправить её легко, в любой нормальной организации её исправят за считанные часы — не нужно иметь пять высших образований и IQ выше 300 чтобы поправить header'ы CORS или просто их убрать (при их отсутствии будут применяться стандартные политики безопасности, которые были бы достаточными и при этом никак не сломали бы работу сервиса).

Проходит рабочий день, решаю поинтересоваться, как успехи:

Обновлено: Как я обнаружил проблемы у ЮМани (Сбербанк) с безопасностью и не получил денег за найденную уязвимость - 7

В ответ тишина. Всё это время уязвимость на месте, по прежнему эксплатируема как и раньше. Статус отчета по прежнему "Рассмотрение". Уточню также, что дополнительно написал CEO ЮМани Ивану Глазачеву: "...через bugbounty.ru сообщил о критической уязвимости в ЮМани, с помощью которой злоумышленники могут получить неограниченный доступ к данным и кошельку пользователей сервиса <...> уязвимость по прежнему на месте. Хотел бы сообщить об этом Вам, дабы избежать ситуации когда из-за промедлений кто-то кроме меня найдет это и решит воспользоваться в преступных намерениях".

И вот спустя два месяца, ночью с 3 на 4 сентября я обнаружил, что уязвимость, наконец, закрыли. Захожу в BugBounty.ru, вижу, что репорт все еще висит в статусе "Рассмотрение". Пишу комментарий:

Обновлено: Как я обнаружил проблемы у ЮМани (Сбербанк) с безопасностью и не получил денег за найденную уязвимость - 8

На следующие сутки на репорт отвечает сотрудник ЮМани:

Обновлено: Как я обнаружил проблемы у ЮМани (Сбербанк) с безопасностью и не получил денег за найденную уязвимость - 9

Отчёт закрывается с переводом в статус "Дубликат" и всё. Мне, тем временем, предлагается поверить, что на протяжении 2 месяцев критическая уязвимость была на их сайте, им якобы об этом было известно и они не предпринимали абсолютно никаких мер по её устранению, пока я не направил им отчёт. А потом совершенно случайно так совпало, что я им написал и они закрыли эту уязвимость. При этом никаких ссылок не приводится, а общее число отчетов на сайте сервиса для баг-репортинга не изменилось. При этом до закрытия уязвимости отчет в статус "Дубликат" никто не переводил, в том числе, сотрудник, принявший отчет в работу изначально.

Обновлено: Как я обнаружил проблемы у ЮМани (Сбербанк) с безопасностью и не получил денег за найденную уязвимость - 10

При этом в условиях программы обещается до 400 тысяч рублей за предоставленную информацию о критической уязвимости.

Обновлено: Как я обнаружил проблемы у ЮМани (Сбербанк) с безопасностью и не получил денег за найденную уязвимость - 11

Отличная схема, скажу я вам. Заводите bugbounty программу на стороннем ресурсе без внешнего аудита и какой-либо репутации, получаете бесплатно репорты об уязвимостях, закрываете их, а сообщившим говорите "дубликат, денег не будет" и всё. Такой вот сайберсекьюрити на бесплатном аутсорсе. Мне кажется, смахивает на мошенничество.

Итог

Из вышесказанного можно делать выводы. Подобное отношение к bug bounty программе у Сбера/ЮМани показывает, чего стоят безопасность пользователей, их данных и денег для сервисов таких компаний. Дискредитируя такими действиями программы репортинга уязвимостей, они создают условия, в которых независимые исследователи не будут проводить исследования т.к. они заведомо будут знать о том, что вознаграждения они не увидят. Зато этим займутся злоумышленники, которые в лучшем случае, продадут информацию третьим лицам, а в худшем — украдут ваши деньги и личные данные.

Такие дела.

Обновлено 09.09.2024:

Как и ожидалось, никаких подтверждений того, что действительно уязвимость была ранее известна — не представили. Вместо этого сказали "это подтверждается нашими внутренними документами" и всё, а документы мы вам не покажем, поверьте нам на слово :-)

Обновлено: Как я обнаружил проблемы у ЮМани (Сбербанк) с безопасностью и не получил денег за найденную уязвимость - 12

Обнародовали ли они хотя бы какое-то косвенное подтверждение сказанного? Нет. Ни скриншотов, ни самих документов, ни тикетов, ни отчетов.

Обновлено 18.09.2024:

После выхода публикации на Хабре, вышеупомянутая площадка Bugbounty.ru (кстати, напрямую аффилированная с самим ЮМани, как выяснилие) молча удалили мою учётную запись c отчётом об уязвимости, будто их никогда не существовало. Сохраненные в Password Manager'е пароль и email при попытке входа теперь возвращают ошибку, а попытка восстановить пароль говорит, что такого пользователя больше не существует. Очень ответственный, профессиональный подход 👍(нет)

А нет больше такой учётной записи

А нет больше такой учётной записи

Автор: alxdrlitreev

Источник

  1. ЮMoney:

    Обращение является дублирующим, это подтверждается нашими внутренними документами. Мы предоставили все необходимые подтверждения дубля репортинга площадке. По правилам программы, вознаграждение за дубли не выплачивается.

    Площадка подтвердила, что мы ей предоставили доказательства, что баг был зафиксирован раньше обращения.


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js