Is ЮБуст - VPN для YouTube. Обход блокировки Ютуб без ВПН. VPN для браузера safe?
ЮБуст is medium risk. ЮБуст ships a hardcoded GA ID (G-XCPV2XK66M) and API secret, logging installs, signups, rival extensions found, and other events. Two permanent UUIDs, made on first run, tag every event, tracking one install across restarts.…
Who publishes itIP Zamolotskikh - no other listings under this identity, 4 shared hostnames
IP Zamolotskikh - no other listings under this identity, 4 shared hostnames
What this publisher told the store about itself, and the other listings that told it the same thing.
Shared hosts - 4 hostnames
Hostnames hardcoded in this extension that few other listings call. That can mean one operator behind both, and it can equally mean a small shared vendor, so it is context rather than a conclusion. Hosts that many listings call are left out: they are services, not connections.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Telemetry to Google Analytics with hardcoded credentials and persistent IDs
ЮБуст ships a hardcoded GA ID (G-XCPV2XK66M) and API secret, logging installs, signups, rival extensions found, and other events.
Two permanent UUIDs, made on first run, tag every event, tracking one install across restarts.
You install ЮБуст or finish onboarding to create your free-trial account.
Same path fires on every browser restart for session events, on every detected conflict with another VPN/ad-blocker extension, and on every uncaught error in the service worker.
ЮБуст posts a JSON event to GA tagged with two permanent per-install IDs, using an API secret hardcoded in the extension.
The same event pipeline carries 'install', 'user_created', 'manual_start', 'video_redirect', 'proxy_controlled_by_other_extension', 'vpn_extension_conflict', 'ad_blocker_conflict', and other lifecycle/observability events, each one stitched to the same persistent client_id.
| Origin | chrome-extension://jddgbeighonaipjikdnfdpiefhoomlae |
| Content-Type | text/plain;charset=UTF-8 |
{
"client_id": "c4aacd99-66ff-46ba-8dba-72e5c45176e7",
"events": [
{
"name": "user_action",
"params": {
"action": "install",
"category": "extension",
"session_id": "1776464941481",
"engagement_time_msec": 100
}
}
]
}| Field | Value | Why it matters | |
|---|---|---|---|
Your permanent client ID | c4aacd99-66ff-46ba-8dba-72e5c45176e7 | A random UUID made on first run, stored forever. Every event carries it, letting the developer stitch your history across sessions. | |
Your permanent device ID | 304bd233-9b22-4f7c-bebc-e9fb1173a3cf | A second UUID kept in storage and a first-party cookie. Clearing storage doesn't remove it; the cookie repopulates it. | |
Session ID | 1776464941481 | Groups the events from one browsing session together. Resets after 30 minutes of inactivity. | |
Event name | user_action / install | Reported action: install, user_created, page_view, manual_start, video_redirect, extension-conflict types, extension_error. | |
Conflicting extension ID + name | cjpalhdlnbpafiamejdnhcphjbkeiagm / uBlock Origin | If another VPN, proxy, or ad blocker is installed, ЮБуст names it and its store ID, so the developer learns which privacy tools you run. | |
YouTube tab URL (on video_redirect) | https://www.youtube.com/watch?v=dQw4w9WgXcQ | When the extension intercepts a video to redirect it through its proxy, the YouTube URL of that tab is sent as the event label. | |
Extension version | 8.10.3 | Which build of ЮБуст is installed. | |
Error message + type | Failed to fetch / user_creation_failed | Any internal error is sent as an 'extension_error' GA event, and also to the developer's own Sentry server. |
The shipped tracker class, with credentials baked in
const Tracker = new class GoogleAnalyticsTracker {
// Reads the persistent UUID from chrome.storage.local under StorageKeys.ClientId.
// If missing, mints a new UUID and saves it. Result: a per-install ID that
// survives forever (until the user explicitly clears the extension's storage).
async getOrCreateClientId() {
const { clientId } = await Storage.get(StorageKeys.ClientId);
if (typeof clientId === 'string') return clientId;
const fresh = self.crypto.randomUUID();
await Storage.set({ [StorageKeys.ClientId]: fresh });
return fresh;
}
// Standard GA4 30-minute rolling session window.
async getOrCreateSessionId() {
const { sessionData } = await Storage.get(StorageKeys.SessionData);
let session = sessionData ? { ...sessionData } : null;
const now = Date.now();
if (session) {
if ((now - session.timestamp) / 60000 > 30) session = null;
else { session.timestamp = now; await Storage.set({ sessionData: session }); }
}
if (!session) {
session = { session_id: now.toString(), timestamp: now };
await Storage.set({ sessionData: session });
}
return session.session_id;
}
// Builds a GA4 Measurement Protocol payload and POSTs it to Google.
// The measurement_id and api_secret are HARDCODED in the URL — anyone
// who unzips the extension can read them; conversely, every install of
// ЮБуст is reporting against the same GA property keyed on client_id.
async sendEvent({ name, params }) {
try {
const [client_id, session_id] = await Promise.all([
this.getOrCreateClientId(),
this.getOrCreateSessionId(),
]);
const body = {
client_id,
events: [{
name,
params: { ...params, session_id, engagement_time_msec: 100 },
}],
};
const url = 'https://www.google-analytics.com/mp/collect'
+ '?measurement_id=G-XCPV2XK66M'
+ '&api_secret=<redacted>';
const resp = await fetch(url, { method: 'POST', body: JSON.stringify(body) });
if (!resp.ok) console.error('Failed to send GA event:', await resp.text());
} catch (e) { console.error('Error sending GA event:', e); }
}
trackPageView(page) {
return this.sendEvent({
name: 'page_view',
params: { page_title: page, page_location: chrome.runtime.getURL(page) },
});
}
trackUserAction(action, category, label) {
return this.sendEvent({
name: 'user_action',
params: { action, category, label },
});
}
trackError(error_message, error_type) {
return this.sendEvent({
name: 'extension_error',
params: { error_message, error_type },
});
}
};// Whenever ЮБуст walks chrome.management to look for other VPN / proxy /
// ad-blocker / 'internal' extensions, it reports each conflict to GA along
// with the OTHER extension's Chrome Web Store ID and human-readable name.
// Result: the developer's GA dashboard tells them which competing privacy
// tools each one of their users has installed.
if (proxyConflict.hasConflictingExtension) {
Tracker.trackUserAction(
'proxy_controlled_by_other_extension',
proxyConflict.conflictingExtensionName ?? 'unknown', // e.g. 'AdBlock Plus'
proxyConflict.conflictingExtensionId, // e.g. 'cfhdojbkjhnklbpkdaibdccddilifddb'
);
}
// Same shape for internal_extension_conflict, vpn_extension_conflict,
// ad_blocker_conflict.
// Onboarding / lifecycle:
await Tracker.trackUserAction('install', 'extension'); // first install
await Tracker.trackUserAction('update', 'extension', previousVersion); // version bump
await Tracker.trackUserAction('user_created', 'premium'); // premium signup
await Tracker.trackUserAction('manual_start', 'proxy'); // proxy started
// YouTube video routing — the YouTube URL is forwarded as the GA event label.
await Tracker.trackUserAction('video_redirect', 'youtube', youtubeUrl);clientId feeds GA; deviceId feeds the dev's backend. Both mint once, never cleared; deviceId is also a cookie, surviving storage clears.
chrome.storage.local, keys 'clientId', 'deviceId', 'sessionData' (and a sibling first-party cookie 'deviceId' on the developer's cookieDomain){
"clientId": "e316df7b-1d92-4aa0-b66d-eed03fe588c7",
"deviceId": "304bd233-9b22-4f7c-bebc-e9fb1173a3cf",
"sessionData": {
"timestamp": 1776464941481,
"session_id": "1776464941481"
}
}- www.google-analytics.com
Receives every Measurement Protocol POST: installs, signups, conflict reports, video redirects, errors. Under GA4 property G-XCPV2XK66M.
- sentry-ws-1.vpnn.space
Self-hosted Sentry owned by the same developer. Receives exceptions, rejections, and arbitrary extras. Tagged extension_code='youboost' (service_worker.js line 1947).
- uboost.space / ubst.space
The developer's backend. Receives the deviceId UUID on trial, signup, and update checks, plus the same UUID as a cookie, re-identifying your install if storage is cleared.
Run this in the ЮБуст service worker's DevTools console to intercept every Google Analytics POST the extension makes and print the full URL (with hardcoded creds), the JSON body, and the resolved client_id/session_id/event params. Confirms the hardcoded credentials and persistent IDs without needing a network proxy.
// uboost-ga-decoder.js
// Drop into the ЮБуст service worker DevTools console:
// chrome://extensions → enable Developer mode → click the
// 'service worker' link under ЮБуст → paste below.
//
// Wraps fetch() so every google-analytics.com/mp/collect call is
// dumped in full BEFORE it hits the wire. Also dumps the persistent
// IDs from chrome.storage.local on load.
(async () => {
// 1. Show the persistent IDs the extension is using to tag your install.
const keys = await chrome.storage.local.get(['clientId', 'deviceId', 'sessionData']);
console.log('[YOUBOOST_IDS] persistent identifiers in chrome.storage.local:');
console.table(keys);
// 2. Hook fetch to capture every GA Measurement Protocol POST.
const origFetch = self.fetch.bind(self);
self.fetch = async function (input, init) {
const url = typeof input === 'string' ? input : input.url;
if (url && url.includes('google-analytics.com/mp/collect')) {
const u = new URL(url);
const measurement_id = u.searchParams.get('measurement_id');
const api_secret = <redacted>('api_secret');
let body = init && init.body;
try { body = JSON.parse(body); } catch {}
console.log('[YOUBOOST_GA] outbound event captured:');
console.log(' hardcoded measurement_id:', measurement_id);
console.log(' hardcoded api_secret :', api_secret);
console.log(' body :', body);
}
return origFetch(input, init);
};
console.log('[YOUBOOST_GA_DECODER] installed. Trigger an event:');
console.log(' - reload the extension to fire "install"/"update"');
console.log(' - install another VPN/ad-blocker to fire "*_conflict"');
console.log(' - open a YouTube video routed through the proxy to fire "video_redirect"');
})();
- 1Open chrome://extensions, enable Developer mode.
- 2Click 'service worker' under ЮБуст.
- 3Paste the script in Console, Enter; it prints stored IDs.
- 4Trigger an event (add a blocker, reload). Each GA POST is dumped with its secret.
Injects its own ad overlays and upgrade banners into the YouTube player
Watching YouTube, this extension can pause your video and cover it with a full-screen overlay loading a remote ad page in an iframe, plus periodic upgrade banners, blocking keyboard shortcuts while up.
Whether it runs is set remotely.
You are watching a video on YouTube.
On a schedule the extension pauses your video and covers the player with its own full-screen overlay that loads a remote ad/upsell page, or shows a premium-upgrade banner.
A background alarm (ShowMidRoll / ShowAdPremiumBanner) messages the active YouTube tab; the content script injects the overlay and blocks keyboard shortcuts until it closes.
The background scheduler and the content-script overlay injector, from the shipping source.
// Background alarm handler for the scheduled mid-roll.
if (alarm.name === Alarms.ShowMidpointMedia) {
const { hasPremium } = await getLocal(Keys.HasPremium);
const { featuresList } = await featureStore.getSnapshotAsync();
const midpointEnabled = Boolean(featuresList?.[Features.MidpointMedia]);
if (hasPremium || !midpointEnabled) return; // skip paying users / disabled flag
const tabs = await chrome.tabs.query({
active: true, currentWindow: true, url: ['*://*.youtube.com/*'],
});
await Promise.all(tabs.map(t =>
t.id ? chrome.tabs.sendMessage(t.id, { action: ContentAction.ShowMidpoint }) : null));
}// Content script: inject the full-screen ad overlay over the player.
const overlay = document.createElement('div');
overlay.id = OVERLAY_ID;
overlay.style.cssText =
'position:absolute;top:0;left:0;width:100%;height:100%;' +
'background:black;z-index:9999;display:flex;justify-content:center;align-items:center;';
const frame = document.createElement('iframe');
frame.id = IFRAME_ID;
frame.src = midpointMediaUrls[regionKey]; // URL comes from downloaded remote config
frame.style.cssText = 'width:100%;height:100%;object-fit:contain;';
window.addEventListener('message', onFrameMessage);
overlay.appendChild(frame);
moviePlayer.appendChild(overlay); // moviePlayer = document.getElementById('movie_player')// Content script: pause playback and swallow YouTube keyboard shortcuts.
const blockKey = (e) => {
if (['', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown',
'k','K','j','J','l','L','m','M','f','F','i','I'].includes(e.key)) {
e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation();
}
};
const pauseForOverlay = () => {
postToPlayerBridge('pauseVideo'); // YT_METHOD_CALL -> injected wrapper
document.querySelector('video')?.pause();
document.getElementById('movie_player')?.pauseVideo?.();
document.addEventListener('keydown', blockKey, true); // capture phase
document.addEventListener('keyup', blockKey, true);
};The page-injected bridge letting the content script drive YouTube's player, in the MAIN world.
// Runs in the page MAIN world (web-accessible resource).
window.addEventListener('message', (event) => {
const data = event.data;
// Only accept the extension's own tagged messages.
if (!(data && data.source === 'YT_API_WRAPPER'
&& data.type === 'YT_METHOD_CALL'
&& ['pauseVideo','playVideo','getPlayerState'].includes(data.method))) return;
const player = document.getElementById('movie_player');
if (!isYoutubePlayer(player)) return;
const result = data.method === 'getPlayerState'
? player.getPlayerState() // -1..5 player state
: (player[data.method](), true);
window.postMessage({ source: 'YT_API_WRAPPER', type: 'YT_METHOD_RESULT',
method: data.method, result }, '*');
});Target: the YouTube player container (#movie_player) on youtube.com/watch
A full-size black overlay div (z-index 9999) holding an ad/upsell iframe is appended over the paused player; the iframe URL comes from downloaded remote config.
<div id="movie_player" class="html5-video-player playing-mode">
<div class="html5-video-container">
<video src="blob:https://www.youtube.com/..."></video>
</div>
<!-- YouTube's own controls -->
</div><div id="movie_player" class="html5-video-player paused-mode">
<div class="html5-video-container">
<video src="blob:https://www.youtube.com/..."></video> <!-- paused by extension -->
</div>
<!-- injected by the extension: -->
<div id="midpoint_overlay" style="position:absolute;top:0;left:0;width:100%;height:100%;background:black;z-index:9999;display:flex;align-items:center;justify-content:center;">
<iframe id="YT_API_WRAPPER_FRAME" src="https://<midpointMediaUrls from remote config>" style="width:100%;height:100%;object-fit:contain;"></iframe>
</div>
</div>Mid-roll overlays and premium-upgrade banners are driven by chrome.alarms, not by anything you do. ShowMidRoll injects the full-screen ad overlay; ShowAdPremiumBanner toggles the banner. Both are skipped for users marked as having premium and are gated by feature flags pulled from remote config, so the cadence and whether they run at all are set by the extension's servers.
What was observed: the YouTube content scripts (including the mid-roll / premium-banner code) were confirmed loaded on a YouTube watch page during dynamic analysis, and the remote feature flags that enable this behavior (video-pre-roll, sidebar-ads) were active in the extension's feature store. The exact ad/upsell pages served are not fixed in the extension — they are URLs the extension downloads from its servers (midpointMediaUrls) and can be changed remotely without an update, so the specific creative shown to any given user is not determined by the shipped code alone.