Недавно мне потребовалось запустить в обычном браузере встроенное в Telegram веб-приложение, называемое Mini App. Объектом изучения стал самый популярный на данный момент кликер Hamster Kombat. Решением стал скрипт для браузерного расширения TamperMonkey, в котором я реализую объект window.Telegram с подмененным свойством platform
для обхода проверки того, что приложение запускается на мобильном устройстве. Но самым интересным оказалось другое.
В процессе поиска решения я наткнулся на любопытное поведение кликера. На этапе аутентификации фронтенд совершает POST-запрос к https://api.hamsterkombatgame.io/auth/auth-by-telegram-webapp
. В теле запроса, помимо данных пользователя Telegram, необходимых для аутентификации, передается свойство fingerprint
, содержащее хэш идентификатора пользователя, и набор информации, характерный для отпечатка браузера.
Что за отпечаток браузера и при чем тут Telegram
Отпечаток браузера, он же fingerprint - это набор информации о браузере и системе пользователя, полученной при посещении веб-страницы. Он может включать в себя:
User-agent
информацию об установленных расширениях;
данные о нюансах работы графического движка браузера;
информацию о железе, сенсорах устройства;
список доступных шрифтов;
часовой пояс;
язык системы
и многие другие данные.
Большинство браузеров обладает своей собственной уникальной комбинацией этих характеристик, пригодной для отслеживания перемещения человека в сети без его ведома. Чистка куков и приватный режим не помогут.
Вы можете проверить, как много информации доступно о вас в браузере с включенным JavaScript на специальном сайте от организации Electronic Frontier Foundation: https://coveryourtracks.eff.org/. Некоторые свойства сужают выборку до сотых долей процента посетителей, а комбинация всех свойств ведёт к одному-единственному браузеру конкретного человека, так что скорее всего вы получите сообщение о том, что отпечаток вашего браузера уникален. Сразу оговорюсь, что данное утверждение справедливо для браузеров без встроенной защиты от отслеживания.
Сайты могут использовать эту технологию для вашей защиты, - например, когда злоумышленник попытается зайти в ваш банковский счет, используя украденные данные, банк затребует дополнительное подтверждение, так как отпечаток браузера изменился. Но отпечаток браузера могут обратить и против вас, вынюхивая ваши действия в ситуациях, когда вы хотели сохранить инкогнито, - например, вы анонимно поменяли криптовалюту через обменник, на котором установлен такой трекер отпечатка. Его владельцы смогут деанонимизировать вас, когда тем же браузером вы зайдете на сайт, где вместе с отпечатком оставите свои личные данные.
Детали находки
Но вернемся к Хомяку. Вот некоторые из параметров, которые я увидел в передаваемом отпечатке: visitorId, fonts, fontPreferences, languages, screenResolution, timezone, platform, vendor, math (acos, acosh, asin...), webGlBasics.
Практически все параметры содержали какое-либо значение. Дополнительно, уже без участия библиотеки, веб-серверу передавались User-agent и IP-адрес пользователя, а из Telegram-клиента передаётся информация о языке пользователя.
Изучив исходники, я выяснил, что для формирования отпечатка использована библиотека fingerprintjs. В своей бесплатной версии она позволяет идентифицировать пользователя с точностью 40-60%, платная же коммерческая увеличивает показатель до 99.5%. В Хомяке используется бесплатная версия 4.2.1, загруженная из каталога npm.
Интересно, подумал я, а возможно ли использовать отпечаток, снятый в браузере Telegram, для отслеживания пользователя вне мессенджера, то есть, в идеале, определять телеграм-аккаунт пользователя при посещении сайта?
В клиенте Telegram используется специально созданный для встраивания браузера компонент. В Android это Android System WebView, в iOS - WebKit. И, чтобы ответить на поставленный вопрос, я решил снять отпечатки со встроенных и обычных браузеров и сравнить степень схожести отпечатков различных браузеров и браузера в Telegram-клиенте. Web-версию Telegram я проверять не стал, так как там и так все очевидно.
Замеры
Для снятия отпечатка браузера я использовал сервис от EFF CoverYourTracks. Он предоставляет статистику по всем характеристикам отпечатка, а именно процент браузеров с идентичными характеристиками среди посетителей сайта за последние 45 дней (примерно 170000 отпечатков).
Чтобы снять отпечаток в Telegram-клиенте, я создал бота, в которого добавил некоторые сайты для снятия отпечатка в качестве мини-приложений, вот он: https://t.me/miniapp_test1_bot
Исследовал я следующие девайсы и браузеры:
Android 11 - смартфон Xiaomi с обновлением от августа 2022. Помимо WebView, я проверил отпечатки браузеров Chrome и Firefox.
GrapheneOS последнего обновления. В этой версии Android в качестве браузера по умолчанию и компонента WebView используется Vanadium, форк chromium с некоторыми изменениями в сторону усиления безопасности. Также проверены Firefox и Brave.
Планшет iPad - последнее обновление. Тут я протестировал WebKit, Safari и Brave.
Я не стал добавлять в таблицу все характеристики отпечатка, только наиболее критичные. Кроме того, я не учитываю IP-адрес пользователя, который может быть изменен при помощи VPN. Но стоит держать в уме, что сам по себе этот адрес также может быть уникальным отпечатком пользователя в сети, - например, если используется персональный VPN-сервер или выделенный IP. Или, как минимум, он может стать тем битом информации, который сузит подмножество посетителей с идентичными вашим характеристиками до вашего устройства.
Результаты замеров
Значения в таблице взяты прямиком из статистики, выданной EFF. Число следует понимать так: каждый n-й браузер обладает этим значением характеристики. Если числа совпадают, то совпадают и значения. Чтобы получить процент браузеров, следует поделить единицу на это число.
Android 11 |
||||||||
---|---|---|---|---|---|---|---|---|
Canvas |
WebGL |
WebGL Vendor & Renderer |
User-agent |
HTTP_ACCEPT |
Platform |
Screen |
Language |
|
telegram (WebView) |
350.28 |
533.05 |
370.84 |
170575 |
42643.75 |
44.9 |
202.1 |
74.75 (en) |
chrome |
350.28 |
533.05 |
370.84 |
258.07 |
156.64 |
8.85 |
202.1 |
49.37 (ru-RU) |
firefox |
170638 |
10037.53 |
450.23 |
170638 |
6319.93 |
44.9 |
202.1 |
49.37 (ru-RU) |
GrapheneOS |
||||||||
telegram (WebView) |
278.83 |
672.27 |
584.48 |
85042 |
56694.67 |
44.9 |
75.23 |
74.75 (en) |
vanadium |
278.83 |
736.31 |
301.57 |
264.93 |
41.77 |
8.85 |
75.23 |
1.74 (en-US) |
firefox |
812.79 |
627.52 |
135.57 |
1855.28 |
18965.11 |
8.85 |
75.23 |
1.74 (en-US) |
brave |
randomized |
randomized |
301.57 |
155.86 |
82.29 |
8.85 |
75.23 |
1.74 (en-US) |
ipad |
||||||||
telegram (WebKit) |
23.44 |
34.42 |
8.71 |
4859.77 |
497.35 |
8.03 |
566.97 |
151.06 (ru) |
safari |
23.44 |
34.42 |
8.71 |
39.27 |
497.35 |
8.03 |
566.97 |
151.06 (ru) |
brave |
23.44 |
34.42 |
8.71 |
39.27 |
497.35 |
8.03 |
566.97 |
151.06 (ru) |
Android
Значение User-agent отличается во всех случаях, поэтому его брать во внимание не будем.
Интереснее выглядят характеристики Canvas и WebGL. Как видим, в случае с Android 11 оба идентичны для браузера в Telegram и для Chrome: свойство WebGL позволяет выбрать 0.0018% пользователей (320 из 170000), Canvas - 0.002% (485 пользователей).
В случае с GrapheneOS свойство WebGL отличается у разных браузеров, но совпадает отпечаток Canvas (611 пользователей).
Интересно, что характеристика Language во встроенном браузере не совпадала с системной на обоих устройствах с Android и всегда равнялась "en". Однако язык пользователя передаётся самим Telegram при аутентификации мини-приложения (свойство language_code
) и может быть использовано для отслеживания.
Для Firefox и Brave ситуация отличается. Встроенная в Brave защита от трекинга устраняет возможность отслеживания по отпечаткам графического движка, так как это значение рандомизировано. Firefox же, построенный на собственном движке, выдаёт совсем другие значения и с WebView не коррелирует.
iOS
Поскольку все браузеры в iOS ограничены движком Safari, все характеристики за исключением User-agent совпадают. При этом, благодаря стандартизированности версий платформы iOS, такие характеристики как Canvas и WebGL не являются сильно специфичными для отдельного девайса. Так, наиболее специфичный WebGL характеризует 2.9% пользователей (5000 из 170000). Тем не менее, множество отслеживаемых пользователей может быть сужено другими характеристиками. Разрешение экрана в моём случае сужает поиск до 300 пользователей из 170000, а характеристика HTTP_ACCEPT - до 340 пользователей.
Далее с помощью еще двух онлайн-сервисов я протестировал, насколько применимы более точные способы идентификации по отпечатку.
Fingerprint.com
Демо-версия коммерческой библиотеки присваивает уникальные идентификаторы visitorId всем браузерам на всех платформах со значением confidence, равным 1. То есть этот идентификатор хорошо работает для отслеживания отдельного экземпляра браузера, но не подходит для перекрестного отслеживания встроенного и основного браузеров, поскольку считает их разными экземплярами. Тем не менее, полная платная версия библиотеки предоставляет разработчику исходные характеристики, использованные для вычисления идентификатора, которые могут помочь связать отпечатки.
browserleaks.com/canvas
Эта версия отпечатка Canvas, в отличие от теста EFF, подобно идентификатору Fingerprint выдала 100% уникальности для всех браузеров на Android, включая WebView. В случае iOS хэш отпечатка Canvas совпадала в WebKit и браузерах. При этом 4000 из 156000 пользователей обладали таким же отпечатком Canvas.
Выводы
Как видите, инструменты для вычисления уникального идентификатора браузера, такие как Fingerprint, не пригодны для отслеживания пользователя через встроенный браузер Telegram. Они слишком точны и считают встроенный и базовые браузеры разными экземплярами. Однако отдельные характеристики, такие как Canvas и WebGL, совпадают и потенциально могут быть использованы для идентификации, поскольку сужают круг поиска среди отпечатков до сотых долей процента посетителей. Решающую роль в отборе могут сыграть IP-адрес пользователя и дополнительный ручной анализ данных о пользователе, добытых из открытых источников.
Для Android необходимым условием является использование посетителем браузера Chrome. Выходит, что пользователю Android для защиты от отслеживания стоит использовать что-то другое - например, Firefox или Brave. Пользователи iOS оказываются в двоякой ситуации: с одной стороны, отпечаток их WebKit практически идентичен любому из доступных браузеров, с другой - этот отпечаток идентичен множеству других пользователей.
А что же Хомяк
Из данных, которые Hamster Kombat отправляет разработчикам, исключены наиболее критичные свойства Canvas и WebGLExtensions, вероятно потому, что они слишком объемные. Таким образом, разработчики лишают себя наиболее ценных в задаче отслеживания характеристик Canvas и WebGL. Оставлено только свойство WebGLBasics (в таблице это столбец WebGL Vendor & Renderer). Отсюда я делаю вывод, что отпечаток снимается не с целью отслеживать пользователей вне Telegram, а для того, чтобы или определять множественные аккаунты одного человека на одном устройстве (через свойство visitorId
), или вычислять запущенных в эмуляторах ботов (через характерный набор данных об устройстве).
Комментарии (6)
decomeron
06.08.2024 12:30+1Мне сразу этот браузер не понравился по этой причине, плюс еще много других недостатков. Спасибо огромное за статью! Кстати, что скажете про Ceno?
sufferer_citric014 Автор
06.08.2024 12:30Кстати, что скажете про Ceno?
Интересный проект. Не слышал про него ранее. Спасибо за наводку!
aax
Есть общий способ решения задачи:
Хранение информации операторами связи и провайдерами(т.н. "Закон Яровой"):
в течение 1 года – данные о фактах передачи, приема, доставки, обработки такой информации (в виде голосовых / текстовых сообщений, изображений, видео, звуковых файлов и т.п.);
в течение 1 года – данные о пользователях, совершивших эти действия;
до 6 месяцев – следует хранить непосредственно саму информацию.
По требованию органов безопасности или оперативно-розыскной деятельности телефонные операторы, провайдеры и иные распространители информации в сетях обязаны предоставлять им сохраняемую информацию. Наличие решения суда не обязательно для исполнения поступившего запроса (Решение судебной коллегии ВС РФ по административным делам № АКПИ18-1109 от 19.12.2018).
Если распространитель информации в сети Интернет использует шифрование для пересылаемых сообщений (мессенджеры, социальные сети и пр.), Роскомнадзору должны передаваться ключи, необходимые для декодирования зашифрованной информации.
*****************
К этому добавлю что Телеграм(в отличии, например от Jami) ещё и изо всех сил противится анонимности пользователей. Не просто месседжер, а настоящий Клондайк для товарища майора.
rsashka
Поменяйте ссылку в комментарии на решение ВС хотя бы на эту https://rulaws.ru/acts/Reshenie-Verhovnogo-Suda-RF-ot-19.12.2018-N-AKPI18-1109/, а то при переходе по вашей требуется регистрации в платной версии Консультант Плюс.
aax
Спасибо за дельную критику, поправил!