Картинка для привлечения внимания взята тут
Пиццерия Папа Джонс открыта во многих странах, движок сайтов же практически везде разный. Тем не менее, движок, который разработали где-то в России, также используется на сайтах для Польши, Киргизии и Беларуси. Его и рассмотрим.
Посмотреть сам движок можно на мобильном сайте для России, к примеру. Почему мобильный? Потому что десктопный не имеет даже формы регистрации, хотя это объяснено тем, что регистрация автоматическая при заказе. Решил я проверить однажды то, как там с уязвимостями дела обстоят.
Так как ковыряться в приложениях проще всего, взял его. К своему удивлению выяснил, что приложение является просто странной оберткой для сайта, хотя и при запросах сервер ясно может отличить, от кого пришел запрос. Тестировать оказалось можно с равным успехом как приложение, так и мобильную версию. Отличие лишь в том, что для мобильного сайта передается поле platform — mobSite, а приложения сообщают систему и версию.
Успеха я достиг сразу же, потому что начал с восстановления пароля. Предлагаю взглянуть на то, как это происходит.
Для начала нужно получить сам код в СМС. Запросим по ссылке с JSON в теле:
POST https://www.papajohns.ru/api/auth/recovery/requestCode
{
"username": "+79номертелефона",
"transport": "sms",
"lang": "ru",
"version": "1.0.34",
"platform": "Android"
}
Сервер отвечает:
{
"status": true
}
Странно, данных мало. Идентификатор или сессию хотя бы, но смотрим дальше.
В СМС приходит четырехзначный код (только цифры). Его мы отправлять не будем, так как смена пароля ведет к блокировке баллов на две недели, а у меня на них планы были. Попробуем отправить случайный:
POST https://www.papajohns.ru/api/auth/recovery/updatePassword
{
"code": "1234",
"password": "123456qwe",
"transport": "sms",
"version": "1.0.34",
"platform": "Android"
}
Я был очень сильно поражен. Получилось так, что при запросе СМС в базу записывается пара номер телефона + код в СМС, а при запросе восстановления по коду сервер проверяет наличие кода в базе и, если код найден, устанавливает принятый пароль в базу.
Ситуация становится хуже от того, что не существует ограничения на перебор кода. Опытным путем я выяснил, что перебором за 10 минут скрипт гарантированно устанавливает пароль. А если запросить восстановления на все 10000 кодов с 0000 до 9999?
12 мая я сообщил все детали непосредственно разработчику сайта (ну, по крайней мере он им представился). 19 июня мне стало интересно, как обстоят дела с закрытием уязвимости. Скрипт отправил около трехсот запросов и встал. Уточнив у разработчика статус, выяснил, что сервер теперь блокирует по IP, если получает 5 некорректных запросов. Сегодня я вновь проверил, не изменилась ли логика, и готов сообщить: не изменилась. Серверу теперь тоже безразлично: я отправил 3000 запросов без особых сложностей, так что и все 10000, полагаю, уйдут без проблем.
Опасность раскрытия всех сохраненных адресов только по наличию номера мобильного телефона остается существенной. Банковские карты удаляются при сбросе пароля. Мне подарили 1000 баллов и пиццу. Пицца вкусная, но адрес я там хранить не буду.