Is Поток – ускоритель YouTube safe?
Поток is medium risk. Turning the YouTube accelerator on has the extension ask its service for a proxy host/port, then install a rule routing YouTube, googlevideo, ytimg, ggpht traffic through it. The lookup POST returned proxy details.…
Who publishes itNAOBOROT LLP - 3 other listings from the same operator, none carrying a finding
NAOBOROT LLP - 3 other listings from the same operator, none carrying a finding
What this publisher told the store about itself, and the other listings that told it the same thing.
Same operator - 3 listings
Published under a different store account, but sharing the registered address, contact or declared legal entity this one gave the store.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
YouTube traffic routes through service-provided proxies
Turning the YouTube accelerator on has the extension ask its service for a proxy host/port, then install a rule routing YouTube, googlevideo, ytimg, ggpht traffic through it.
The lookup POST returned proxy details.
You press the extension's main button to connect the YouTube accelerator.
The popup writes the connected target state when the connection timer still allows a session.
The service worker requests proxy details and configures Chrome to route YouTube-related traffic through the returned proxy.
The PAC script exempts music.youtube.com but routes googlevideo.com, youtube.com, ytimg.com, and ggpht.com.
| Content-Type | application/json |
| Field | Value | Why it matters | |
|---|---|---|---|
YouTube pages | https://www.youtube.com/watch?v=dQw4w9WgXcQ (illustrative) | Your YouTube page visits sit on the proxy path once connected, revealing which host you reach; visibility depends on proxy/TLS handling. | |
Video stream requests | https://rr3---sn-n8v7zn7s.googlevideo.com/videoplayback?id=o-AJirM2F6x9 (illustrative) | Video playback connects through googlevideo.com hosts YouTube selects; those connections can show streaming is happening through the proxy. | |
Thumbnail and image hosts | https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg (illustrative) | Your YouTube image and thumbnail loads are also matched by the proxy rule, adding more page-view context to the proxy path. | |
Music YouTube exception | https://music.youtube.com/watch?v=dQw4w9WgXcQ (illustrative) | Music YouTube traffic is excluded from the proxy rule, so routing targets only other YouTube-related hosts named in the PAC script. |
The service worker fetches a proxy and installs a YouTube PAC rule
async function b() {
try {
const {
extensionData: e
} = await y(w.ExtensionData);
if (void 0 !== e) return e;
const t = await fetch("https://storage.googleapis.com/potok/potok.json");
return await t.json()
} catch (e) {
console.error("Error loading configuration:", e), await m({
currentState: "error"
})
}
}
async function v({
onFail: e
} = {}) {
try {
await m({
currentState: "connecting"
});
const t = await b();
if (!t) return;
const n = t.apiBaseUrl,
r = await async function() {
const {
deviceId: e
} = await f(p.DeviceId);
return e || await async function() {
const e = "xxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (e => {
const t = 16 * Math.random() | 0;
return ("x" === e ? t : 3 & t | 8).toString(16)
}));
return await m({
deviceId: e
}), e
}()
}();
r || console.warn("enableProxy: Failed to retrieve device ID, proceeding without it.");
const o = await async function() {
try {
const e = await fetch("https://api.ipify.org?format=json");
return (await e.json()).ip
} catch (e) {
return console.error("Error fetching public IP:", e), null
}
}();
null === o && console.warn("enableProxy: Failed to retrieve public IP address, proceeding without it.");
const i = await async function({
apiBaseUrl: e,
deviceId: t,
deviceIp: n,
onFail: r
}) {
const o = await fetch(`https://${e}/api/v1/get-proxy`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
device_id: t ?? "unknown",
device_ip: n ?? "unknown",
on_fail: r
})
});
return await o.json()
}({
apiBaseUrl: n,
deviceId: r,
deviceIp: o,
onFail: e
}), {
host: a,
port: s
} = i;
chrome.proxy.settings.set({
value: {
mode: "pac_script",
pacScript: {
data: `\n function FindProxyForURL(url, host) {\n if (dnsDomainIs(host, ".music.youtube.com")) {\n return "DIRECT";\n }\n\n if (dnsDomainIs(host, ".googlevideo.com") ||\n dnsDomainIs(host, ".youtube.com") ||\n dnsDomainIs(host, ".ytimg.com") ||\n dnsDomainIs(host, ".ggpht.com")) {\n return "PROXY ${a}:${s}";\n }\n return "DIRECT";\n }\n `
}
},
scope: "regular"
}, (async () => {
if (chrome.runtime.lastError) await m({
currentState: "error"
}), console.error("Error setting proxy:", chrome.runtime.lastError.message);
else {
const {
connectionCount: e,
targetState: t
} = await f([p.ConnectionCount, p.TargetState]), n = e ?? 0;
"disconnected" === t ? S() : await m({
currentState: "connected",
connectionCount: n + 1
})
}
}))
} catch (e) {
console.error("Error loading configuration:", e), await m({
currentState: "error"
})
}
}
- storage.googleapis.com
Hosts the potok.json configuration that names the extension service domain.
- ptkdfjnflmpalkfpkehjgopmjldhjhgb.click
Receives the proxy-lookup POST and returns the proxy host and port used by the PAC script.
- api.ipify.org
Receives a public-IP lookup before the proxy-selection request is made.
Remote JSON Config Controls Which Server Receives Your Device ID and IP
On every startup, the extension fetches config from storage.googleapis.com/potok/potok.json.
Its apiBaseUrl decides where your device ID and IP go on connect.
Four GETs confirmed ptkdfjnflmpalkfpkehjgopmjldhjhgb.click received the data.
You open your browser with the extension installed.
The extension fetches a JSON config from Google Cloud Storage and reads apiBaseUrl. Later requests carrying your device ID and public IP go to the domain named there.
The config can change at any time without an extension update, any domain can be placed in apiBaseUrl.
Config-loading code from the extension's shipping source:
// Loads the remote configuration. Returns cached session copy if available.
async function loadConfig() {
try {
// Check session storage cache first
const { extensionData } = await chrome.storage.session.get('extensionData');
if (extensionData !== undefined) return extensionData;
// Fetch from Google Cloud Storage — no SRI, no domain validation
const response = await fetch('https://storage.googleapis.com/potok/potok.json');
return await response.json();
// Returned object contains: { apiBaseUrl: "<hostname>" }
// This hostname is used directly for the POST /api/v1/get-proxy call
} catch (e) {
console.error('Error loading configuration:', e);
await chrome.storage.local.set({ currentState: 'error' });
}
}Because the API base URL is fetched fresh from storage.googleapis.com/potok/potok.json on every browser startup, the owner of that file can point the data recipient to any domain at any time. Users receive no notification when this changes. The extension does not validate the returned domain against any allowlist, and there is no Subresource Integrity (SRI) check on the fetched JSON.
- storage.googleapis.com
Google Cloud Storage bucket 'potok' serving the runtime config file potok.json. Controls the destination for all device data.
- ptkdfjnflmpalkfpkehjgopmjldhjhgb.click
Proxy API endpoint resolved from potok.json at the time of our test session. Received POST requests with device_id and device_ip.
Persistent Device UUID Stored and Reused Across All Browser Sessions
On first connect, the extension makes a UUID, stored as 'deviceId'.
It persists across restarts and rides every proxy-API connect.
Confirmed written on first use and unchanged in later POSTs, letting the server link all your sessions.
You click connect for the first time after installing the extension.
The extension makes a UUID and saves it to storage.local. Every later connect, in any future session, retrieves and sends this same UUID to the proxy API.
There is no mechanism in the extension UI to view, reset, or delete this identifier.
Written after your first connect, unchanged across restarts. Appears verbatim as device_id on every POST to /api/v1/get-proxy.
chrome.storage.local key 'deviceId'{"deviceId":"b691591-2e2b-45f5-8a34-f3ee0f36967d"}UUID generation and storage from the extension's shipping source:
// Retrieves the stored device ID, or generates and stores a new one.
const deviceId = await (async () => {
const { deviceId } = await chrome.storage.local.get('deviceId');
if (deviceId) return deviceId; // reuse existing UUID
// Generate a new UUID via Math.random() (not crypto.getRandomValues)
const newId = 'xxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
const r = Math.random() * 16 | 0;
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
await chrome.storage.local.set({ deviceId: newId }); // persists across sessions
return newId;
})();Reads the 'deviceId' stored by the Поток extension from chrome.storage.local via the Chrome command-line debugger. Run this to confirm whether the extension has assigned a persistent identifier to your browser.
#!/usr/bin/env bash
# check-potok-device-id.sh
# Reads the deviceId from Поток's chrome.storage.local.
# Requires Chrome with remote debugging enabled.
#
# Usage:
# 1. Launch Chrome with: --remote-debugging-port=9222
# 2. Run: bash check-potok-device-id.sh
EXT_ID="ocionjkjaapcailghfnhnjkpapepelib"
DEBUG_URL="http://localhost:9222"
# Find the service worker target for this extension
SW_URL=$(curl -s "${DEBUG_URL}/json" | python3 -c "
import sys, json
for t in json.load(sys.stdin):
if '${EXT_ID}' in t.get('url','') and t.get('type') == 'service_worker':
print(t['webSocketDebuggerUrl'])
break
")
if [ -z "$SW_URL" ]; then
echo "ERROR: Could not find Поток service worker. Is the extension installed and Chrome running with --remote-debugging-port=9222?"
exit 1
fi
echo "Querying storage via: $SW_URL"
# Evaluate chrome.storage.local.get('deviceId') in the service worker context
python3 << PYEOF
import asyncio, json, websockets
async def read_storage():
async with websockets.connect('${SW_URL}') as ws:
await ws.send(json.dumps({
'id': 1,
'method': 'Runtime.evaluate',
'params': {
'expression': 'chrome.storage.local.get("deviceId").then(r => JSON.stringify(r))',
'awaitPromise': True
}
}))
result = json.loads(await ws.recv())
value = result.get('result', {}).get('result', {}).get('value', 'null')
data = json.loads(value)
if 'deviceId' in data:
print(f'[FOUND] deviceId = {data["deviceId"]}')
else:
print('[NOT FOUND] No deviceId stored yet. Connect the extension first.')
asyncio.run(read_storage())
PYEOF- 1Launch Chrome with remote debugging: google-chrome --remote-debugging-port=
- 29
- 32
- 42
- 5
- 6Install the Поток extension and click connect once.
- 7Run: bash check-potok-device-id.sh.
- 8The output shows your assigned device ID.
What it can do
Permissions this extension asks for, as declared in version 1.1.1. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to. The current listed version is 2.0.5, which we have not unpacked yet.
Read and change your data on youtube.com
https://*.youtube.com/*
Route all of your browsing through a server of its choosing
proxy
Store data in your browser
storage
Watch every request your browser makes
webRequest
Act on the current tab, but only after you click the extension
activeTab
See the address and title of every tab you have open
tabs