Привет! Меня зовут Дмитрий Терёшин, я работаю в отделе AppSec в компании СберМаркет. Моя работа — обеспечивать безопасность наших онлайн сервисов для его клиентов и бизнеса в целом. Недавно мы запустили Bug Bounty программу на BI.ZONE, чтобы независимые багхантеры могли помочь нам в поиске уязвимостей и в честь этого хотим поделиться подборкой багов безопасности в e-com. Для СберМаркета эти уязвимости уже не актуальны, но, не будем скрывать, что некоторые из них мы встретили на своем пути, так что поделимся не только угрозами, но и методами защиты.
За отлов актуальных уязвимостей мы готовы награждать суммой до 250 000 рублей — прочитать подробнее про наш Bug Bounty можно вот тут. Поехали!
Уязвимости оплаты
Самый критичный функционал, который существует в интернет-магазинах, связан с оплатой, промоакциями и аутентификацией. Именно там злоумышленники чаще всего ищут уязвимости. Начну с кейсов фрода с различными механиками оплаты.
Подмена суммы
Уровень угрозы: Critical
В любом интернет-магазине есть функциональность корзины: покупатель набирает в нее товары, размещает заказ, затем оплачивает его. Обычно магазин использует сторонний эквайринг, и, если его API уязвим или интеграция настроена некорректно, злоумышленник может перехватить запрос и в поле amount и подменить сумму в меньшую сторону, например, указать сумму 1 рубль вместо полной суммы и отправить запрос дальше. В итоге оплата произойдет на 1 рубль, но привезут мошеннику полный заказ.
Меры защиты: корректно настраивать интеграцию с эквайрингом, проверять итоговую сумму заказа.
Отмена позиций в заказе
Уровень угрозы: Critical
Следующий кейс — фрод с отменой позиций. В стандартном флоу клиент собирает корзину через интерфейс сайта, далее заказ падает к сборщику — в магазин или на склад, где товары собирают с полок для доставки клиенту.
В функционал некоторых e-com проектов входит возможность отменить или заменить товарную позицию, если она не найдена на полке. В этом случае сборщик удаляет товар из заказа, либо меняет его на другой — с большей или меньшей стоимостью. В этом случае конечная сумма оплаты появляется только после того как в итоге заказ валидирован сборщиком и клиентом.
На этом этапе пользователь уже не должен иметь возможность удалять позиции из корзины, и кнопка «Удалить товар» отсутствует в интерфейсе. Однако злоумышленник может попробовать удалить позицию в тот момент, когда сборщик добавил ее в корзину прямым запросом в API. То есть он видит на сайте, какой товар уже добавлен, а какой еще нет, и, как только сборщик добавляет его, дергает за соответствующую ручку в API и удаляет из корзины, соответственно сумма заказа уменьшается — можно оставить один самый дешевый товар и оплатить только его, а привезут полный заказ.
Меры защиты: продумывать возможные уязвимости во флоу заказа на этапе архитектуры сервиса, использовать меры защиты не только на клиенте, но и на сервере
Уязвимости с промокодами
Одна из особенностей e-com в том, чтобы регулярно придумывать новые механики стимулирования спроса и возвращения клиентов. Здесь на сцену выходят различные промо. Сперва поговорим о промокодах — механике, которая давно стала общим местом в индустрии.
Предсказуемые значения
Уровень угрозы: Low
Маркетологи часто используют различные сезонные события и праздники как повод, чтобы запустить промо. Привязывая акции к этим событиям, значения промокодов нередко формируются по следующему принципу:
предсказуемый префикс (например, на 1 сентября — school, на новый год — newyear)
суффикс (короткое число в 3-5 цифр)
Ориентируясь на это правило, можно попробовать перебирать промокоды и таким образом сделать себе скидку.
Другой кейс — попробовать какое-нибудь тестовое значение промокода, например, test123456 — иногда такое тоже попадает на прод.
Меры защиты: генерировать длинные случайные значения промокодов и устанавливать систему лимитов для защиты от их перебора.
Утечки промокодов
Уровень угрозы: Low
Следующая уязвимость — это утечки промокодов в сторонние сервисы. У любого интернет-магазина есть админка и доступ к ней как правило хорошо защищён, но если при навигации по админке в URL-ы попадают значения промокодов, то такая информация может утекать на сторону сервиса аналитики (если он забирает URL-ы). Так промокоды могут утекают в неизвестном направлении, и вы не имеете над ними контроль.
Другой популярный способ вытащить промокоды и какие-нибудь персональные данные из админки вплоть до доступов админа — использовать stored-XSS в каком-то поле заказа, например «Комментарии к заказу». Если значение этого поля не валидируется, можно подкинуть payload, который заберет cookie админа и отправит её на чужой домен.
Меры защиты: отключать аналитику для разделов просмотра промокодов.
Гонки с промокодами
Уровень угрозы: Medium
Эта группа уязвимостей включает в себя разные схемы по неоднократному использованию промокодов. Бизнес-логика любого интернет-магазина подразумевает, что вы применяете только один промокод к одному заказу и таких кейсов быть не должно, но если в бекенде системы лояльности есть уязвимости, то могут случиться следующие неприятные кейсы.
Первый способ — зафиксировать ID заказа. Если кто-то знает конкретный промокод, допустим, на 100 рублей, то может попробовать параллельно запустить запрос в несколько потоков. Если промокоды просуммируются, с 10 одновременных запросов кто-то получит скидку на 1000 рублей.
Другой вариант — попробовать применить два разных промокода одновременно и получить двойную скидку.
Меры защиты: использовать блокировки и транзакции при запросах в БД.
Уязвимости с промо-акциями
Промокоды — не единственное, что могут рассылать клиентам для стимулирования продаж. Часто в рамках сезонных маркетинговых активностей или для проверки гипотез по базе клиентов рассылают различные ссылки. Поговорим о том, какие уязвимости могут в них скрываться.
Промокоды в открытом виде
Уровень угрозы: Low
Часто бывает, что отделу маркетинга нужно протестировать гипотезу и пользователям присылают ссылку на лендинг, где клиенту нужно в игровой форме выбрать варианты ответа, а в конце он получит подарок — промокод.
Если в эту ссылку, которую рассылают на почту или в sms-ках клиентам, прямо в url вставить промокод, догадливый пользователь может это заметить: скопировать его, вставить и применить — без лишних телодвижений.
Меры защиты: отдавать промокод в конце прохождения игровой активности.
Ссылки на подтверждение почты и восстановление пароля
Уровень угрозы: Medium
Допустим, есть рекламный лендинг (например, новогодняя акция) с какой-то активностью (например, розыгрышем). Происходит массовая рассылка акции на клиентов: клиент получает ссылку, переходит по ней, ему предлагают зарегистрироваться по почте на этом лендинге, он вводит почту и ему говорят: «Перейдите по ссылке которая прислана вам на почту, чтобы подтвердить, что она вам принадлежит», — клиент переходит, задает пароль и регистрируется для участия в акции.
Обратим внимание на ссылку в письме: внутри есть хвост в виде base64 последовательности. Если его декодировать, там два непредсказуемых параметра:
ID пользователя, который инкрементально увеличивается на единичку, то есть это не какой-нибудь непредсказуемый UUID
короткий код подтверждения — 6-8 символов. Это строчные латинские буквы с цифрами, то есть пространство перебора довольно небольшое.
На основании этой информации можно предположить следующий ID и зарегистрировать аккаунт на чужую почту.
Аналогичная история с восстановлением пароля: если есть кнопка «Восстановить пароль», кто-то может декодировать base64 в конце и увидеть два параметра: код и логин (он же e-mail). Если человек будет знать, что какой-то конкретный e-mail зарегистрирован, он сможем попасть в его аккаунт, перебрав 8 символов, сменить пароль и войти под новым измененным паролем.
Меры защиты: генерировать длинные случайные последовательности для ссылок подтверждения email-а/восстановления доступа, делать эти ссылки одноразовыми с коротким сроком жизни и устанавливать лимиты на количество попыток подтвердить почту/восстановить доступ.
Открытие произвольного URL-а в приложении
Уровень угрозы: Medium
Для мобильных приложений маркетинговые рассылки часто происходят через sms или push-уведомления. При нажатии на них мобильное приложение поднимает диплинк, открывает во встроенном браузере WebView url, находящийся внутри, и, если там нет никакой валидации по белому списку, кто-то может подсунуть пользователям свою зловредную ссылку.
Меры защиты: проверять передаваемые через диплинки url-ы по белому списку.
Аутентификация
Последнее, о чём хочется поговорить — это аутентификация. Здесь бизнесу всегда приходится идти на компромисс между безопасностью и скоростью для пользователя. Расскажу о нескольких схемах, от которых не сложно защититься при этом не ухудшив клиентский опыт.
Вход по SMS
Уровень угрозы: Critical
Пользователей интернет-магазинов обычно не заставляют задавать пароли, чтобы не усложнять им жизнь, то есть там есть только один фактор — вход по одноразовому паролю из sms. Обычно это 5 или 6 цифр. Если нет никаких лимитов по количеству попыток, злоумышленник может перебрать эти 6 символов и попасть в чужой аккаунт, после чего поменять адрес доставки и получать заказы за чужой счет.
Другой способ — зафиксировать в sms конкретное значение otp и сделать горизонтальный перебор по номерам телефонов. Если у otp нет срока жизни и он не инвалидируется после использования, базу телефонных номеров можно перебрать и наткнуться на номер, которому этот otp подойдет.
Меры защиты: настроить систему лимитов для методов аутентификации, делать otp действительно одноразовым и с коротким сроком жизни.
Вход по пин-коду
Уровень угрозы: High
Кроме основного мобильного или веб-приложения магазина существуют сервисы для курьеров, сборщиков и других партнеров компании. Например, приложение, в которое будущий партнер загружает свои документы, чтобы передать их отделу кадров и службе безопасности.
Обычно для упрощения входа в такие приложения создают пин-код. Классически это реализуется так: клиент вводит свои креды, ему предлагается создать пин-код при первом входе, он задает его и далее он хранится и проверяется локально, то есть не отправляется на backend.
Соответственно, если есть кнопка «Не могу войти», и при этом там не проверяется старый пин-код, то есть лазейка создать там новый пин и войти. access токен будет успешно отправлен на сервер, и кто-то попадёт в чужой аккаунт.
Меры защиты: реализовывать вход по пин-коду с участием бэкенда. Для сброса пин-кода отправлять пользователя на аутентификацию по кредам и делать логаут — инвалидировать текущий refresh токен и подчищать его на клиенте.
Подпись запроса и захардкоженный ключ
Уровень угрозы: Medium
Некоторые компании в своих продуктах пытаются защитить свою API через подпись параметров запроса в надежде, что так их API будут абъюзить меньшее количество народа. Это может быть реализовано с помощью HMAC, просто хэша или более сложного алгоритма подписи от всех параметров запроса на клиенте — подставлять его в запрос и проверять на сервере. Как правило это HMAC, ключ для которого зашит на клиенте.
Я встречал такую ситуацию: есть url с параметром sig в конце (без него возвращается Bad Request). По его длине можно предположить, что это хеш MD5, у которого длина дайджеста 128 бит.
Если это мобильное приложение,можно декомпилировать его, посмотреть в исходниках алгоритм, найти функцию, которая формирует подпись, увидеть, что это просто конкатенация всех query параметров запроса с добавлением секретного ключа, который захардкожен в самом приложении, посчитать хеш и отправлять запросы в API.
Если это веб-приложение, тоже можно посмотреть в исходниках самой веб-страницы — возможно, там будет зашит такой ключ.
Меры защиты: не хардкодить ключи на клиенте.
На этом у меня всё. Надеюсь, вы нашли эту статью интересной и смогли извлечь полезные для себя знания. А если вы найдете какую-нибудь уязвимость в СберМаркете, то знаете, куда можно её отправить: https://app.bugbounty.bi.zone/companies/sbermarket/main
Tech-команда СберМаркета завела соцсети с новостями и анонсами. Если хочешь узнать, что под капотом высоконагруженного e-commerce, следи за нами в Telegram и на YouTube. А также слушай подкаст «Для tech и этих» от наших it-менеджеров.
dartraiden
Я очень удивился, когда в прошлом году узнал, что подмена суммы в запросе до сих пор актуальна.
Лет 13 назад я таким макаром купил за цент софт, который стоил 50 баксов. Прислали лицензионный ключ, а через какое-то время вдогонку просьбу "Please do not place fraud orders", но ключ не забанили.