Уязвимость партнерки

По одному из наших проектов мы участвуем в партнерской программе по привлечению покупателей. В соответствии с договором, который мы подписали с организатором партнерки, мы размещаем на своих ресурсах ссылки вида <a href='http://site.com/ref=code'>text</a>. Если пользователь переходит по ссылке, то для него открывается сессия на 48 часов, и со всех покупок в течении этого времени нам полагается партнерский процент. Причем, даже если пользователь закрывает браузер, выключает компьютер, то сессия не прерывается, и все покупки в течении 48 часов все-равно засчитываются.

Уязвимость партнерской программы

Однажды кофе было вкусное, ночь бессонная, а руки чесались что-нибудь поисследовать. В итоге, выбор на изучение принципа работы данной партнерской программы, которое закончилось нахождением в ней уязвимости.

Хочется сразу отметить, что организатор партнерской программы является крупной компанией, одним из лидеров отрасли, и надежд найти что-то интересное я не питал. Мне было просто интересно посмотреть как у них все устроено.
Размышляя о том, как же они отслеживают, что пользователь изначально пришел от партнера, я в первую очередь логично подумал, что все дело в cookies. Но оказалось, что это не так. Сайт продавца ставил много печенек, но опытным путем удалось установить, что даже их полное удаление не рушит сессию.

Не придумав ничего умнее, я решил проверить как влияют на сессию смены IP-адресов, браузеров, разрешений экрана и прочих параметров.
Опытным путем было установлено, что клиент идентифицируется по следующим параметрам:

  • IP-адрес;
  • User-agent браузера;
  • Локаль браузера.
  • Немного странные набор, который не позволяет в полной мере идентифицировать пользователя. Не ожидал такого от компании с многомиллионным оборотом, но, что есть, то есть.

    Следующей мыслью было «А что если разместить на сайте код вида <img src='http://site.com/ref=code'/> и выводить на всех страницах сайта?» Когда в партнерской панели я увидел, что после посещении страницы с таким кодом образовалась сессия, я уже даже не удивился. Естественно, браузер пользователя попытался загрузить изображение, но вместо него запросил страницу сайта, тем самым эмулировав ее посещение пользователем.

    Обсудив эту уязвимость внутри своей команды, мы решили сообщить о ней разработчикам. Все-таки так честнее, могут исключить из партнерской программы, да и используя подобный прием, наши конкуренты могут перехватывать наших пользователей (Если человек перешел сначала по одной ref ссылке, затем по другой и совершил покупку, то она засчитывается владельцу второго ref-кода).

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

    function img() {
          var img = document.createElement('img');
          img.setAttribute('src', 'http://site.com/ref=code');
          document.body.appendChild(img);
    }

    Обфусцировав и спрятав этот кусок кода среди сотен килобайт другого JS, можно значительно затруднить поиск запроса страницы.
    Также мы знаем по какому принципу идет идентификация пользователей и срок жизни сессии, а следовательно на своей странице можем самостоятельно определять новый ли это пользователь и стоит ли выводить ему на странице JS код для создания сессии. Тем самым мы еще сильнее затрудним поиск кода, который эксплуатирует уязвимость.

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

    Более чем уверен, что в интернете еще множество партнерских программ, которые реализованы по подобному принципу. Надеюсь, что после этой статьи уязвимых сервисов станет меньше.

    Leave a Reply