Is VPN Наружу для YouTube. Обход блокировки YouTube бесплатно safe?

Medium risk

The extension fetches its proxy configuration and PAC script from remote servers with no integrity verification.

On every connection, the extension retrieves a configuration JSON from storage.googleapis.com (with a Yandex Cloud fallback) to obtain its proxy server address and the URL of a PAC script. The PAC script itself is downloaded, decompressed client-side, and applied directly to browser proxy settings without any signature or integrity check, meaning a compromised or substituted config file could redirect all browser traffic. The extension also enumerates all installed browser extensions every 30 minutes and writes a user ID cookie to a domain specified by the same remote config.

apps.vpn.naruzhuv2.5.0Chrome Web Store
50Risk
Who publishes it

apps.vpn.naruzhu - no other listings under this identity, 3 shared hostnames

What this publisher told the store about itself, and the other listings that told it the same thing.

Publisher
apps.vpn.naruzhu

Shared hosts - 3 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.

cuknrz.top
Also called by 1 other listing: TwiHD
naruzhu.click
Also called by 4 other listings
staticfiles.cukubst.top
Also called by 4 other listings

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

VPN proxy routing rules are fetched from a remote server with no integrity check

HighunwantedCWE-829Dynamic sandbox

This VPN/proxy extension routes traffic through proxy servers.

What actually happens

You did this

You install the extension and the background service worker starts.

No interaction beyond loading the extension is required; the configuration fetch fires automatically on service-worker startup.

The extension did this

The extension fetches its proxy routing rules from a remote server and applies them with no integrity check.

A three-stage fetch chain retrieves a PAC (Proxy Auto-Config) script whose URL is supplied by a remote registry, then applies it via chrome.proxy.settings.set to route browser traffic.

Captured request

GEThttps://storage.googleapis.com/uboost-neo/pca-scripts-registry-google.json

Returns a registry of PAC-script URLs. The selected URL (e.g. https://staticfiles.cukubst.top/pacs/free-pac-script.json) was then fetched and returned status 200, recorded in storage.session under apiHttpSuccess. Observed during dynamic analysis on service-worker startup, before any login.

Remote sources that determine how your traffic is routed

    • storage.googleapis.com

    Hosts naruzhu.json (meta config) and the PAC-script registry uboost-neo/pca-scripts-registry-google.json. Google Cloud Storage bucket controlled by the extension operator.

    • storage.yandexcloud.net

    Fallback config host (vpnn-web-configs/...). Yandex Cloud Storage bucket used when the Google bucket path is selected as fallback.

    • staticfiles.cukubst.top

    Hosts the actual PAC script payload (pacs/free-pac-script.json) fetched in our session. Operator-controlled domain.

    • extension.nrz.homes

    apiBaseUrl returned by naruzhu.json; serves /api/v2/get-proxy, which returns the proxy host and port used to route traffic.

The code that does this

The PAC-script URL comes from a remote registry; the decompressed script becomes the proxy config.

Readable version

Stage 1: meta config endpoint selected and fetched as JSON

background/service_worker.js
const path = devMeta ? 'naruzhu/naruzhu-test.json?version=3' : 'naruzhu/naruzhu.json';const metaUrl = await resolveConfigBaseUrl(path);            // -> storage.googleapis.com or yandexcloud fallbackif (!metaUrl) throw new Error('No meta API URL provided');const meta = await http.get(metaUrl.toString()).json();     // { apiBaseUrl, cookieDomain, ... } -- NO integrity check

Stage 2: PAC-script registry URL is server-selectable, fetched as JSON

background/service_worker.js
const regName = devMeta ? 'uboost-neo/pca-scripts-registry-google-test.json'                        : 'uboost-neo/pca-scripts-registry-google.json';const regUrl = (configBase === 'https://storage.yandexcloud.net/vpnn-web-configs/')  ? new URL(devMeta ? 'uboost-neo/pca-scripts-registry-yandex-test.json'                    : 'uboost-neo/pca-scripts-registry-yandex.json', configBase)  : new URL(regName, 'https://storage.googleapis.com/');return await http.get(regUrl.toString()).json();            // registry -> per-tier PAC-script URLs

Stage 3 / apply: decompressed PAC string applied with no signature or SRI

background/service_worker.js
const pac = buildPac({ host, port, pacString, shouldDecompress, vpnHost, vpnPort });const proxyConfig = { mode: 'pac_script', pacScript: { data: pac } };await chrome.proxy.settings.set({ value: proxyConfig, scope: 'regular' });// No signature check, no Subresource Integrity, no pinned hash on any fetched file.

The code that does this

Proxy host and port also come from the remote apiBaseUrl

Readable version
async function getProxy({ apiBaseUrl, deviceId, deviceIp, onFail }) {  const { featuresList } = await features.getSnapshotAsync();  // apiBaseUrl itself came from the remote naruzhu.json config  return await http.post(`https://${apiBaseUrl}/api/v2/get-proxy`, {    json: { product: 'naruzhu', device_id: deviceId, device_ip: deviceIp ?? 'unknown', on_fail: onFail, with_auth: featuresList[Feature.ProxyAuth] }  }).json();   // returns the proxy host/port that traffic is routed through}

What we did and did not observe

We observed the full remote configuration fetch chain (naruzhu.json -> PAC registry -> PAC script, status 200) fire on service-worker startup before any login. The final chrome.proxy.settings.set application step is gated behind an email one-time-password login wall that we did not pass in this session, so we did not observe traffic being actively re-routed. The remote-controlled, integrity-unchecked source of the routing rules — the substance of this finding — was fully demonstrated.

Remote config picks which domain the extension writes account cookies to

MediumunwantedCWE-829Dynamic sandbox

When userId or deviceId changes in local storage, the extension writes them as cookies to a domain read from remote config naruzhu.json.

What actually happens

You did this

Your userId or deviceId changes in the extension's local storage.

A chrome.storage.onChanged listener watches for these identifier values changing.

The extension did this

The extension writes the identifier as a cookie to a domain it reads from a remote config file.

The destination is the cookieDomain field returned by storage.googleapis.com/naruzhu/naruzhu.json, not a hardcoded value in the extension.

Captured request

GEThttps://storage.googleapis.com/naruzhu/naruzhu.json

Response body observed during dynamic analysis: { apiBaseUrl: extension.nrz.homes, cookieDomain: cuknrz.top, currentVersion: 2.0.0, supportedBrowsers: [...], proxy: ... }. The cookieDomain value (cuknrz.top) is what the extension then wrote cookies to.

Values written to the remote-config-supplied cookie domain (observed)

  • Account identifier (userId)
    userId = <redacted>@example.com

    The userId cookie carried the account identifier; in our session this was the email address entered at the login screen.

  • Device identifier (deviceId)
    deviceId = 5f3c2a91-8b04-4e77-9c1a-2d6e0f4ab123

    A per-install device identifier, read and written to the same remote-config-supplied domain.

  • Destination domain (cookieDomain)
    cuknrz.top

    The domain cookies are written to, read from the remote naruzhu.json config, so a server change redirects where these identifiers are set.

The code that does this

Cookie write/read target their URL at the remote-config cookieDomain

Readable version
// cookieDomain is destructured from the remote meta config (naruzhu.json)async function setIdentifierCookies(entries) {  const { cookieDomain } = await getMetaConfig();        // <- remote-supplied  for (const [name, value] of Object.entries(entries)) {    await chrome.cookies.set({ url: `https://${cookieDomain}`, name, value, ...opts });  }}async function getIdentifierCookie(name) {  const { cookieDomain } = await getMetaConfig();        // <- remote-supplied  const c = await chrome.cookies.get({ url: `https://${cookieDomain}`, name });  return c ? { [name]: c.value } : { [name]: null };}

The code that does this

storage.onChanged listener triggers the cookie write when the identifier changes

Readable version
chrome.storage.onChanged.addListener(changes => run(async () => {  // identifier changes in storage.local are mirrored out to the cookieDomain  // by setIdentifierCookies({ userId } / { deviceId }) on change.  ...}));

What it can do

Permissions this extension asks for, as declared in version 2.5.0. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.

  • Read and change your data on youtube.com

    https://*.youtube.com/*

  • Read and change your data on youtu.be

    https://*.youtu.be/*

  • Read and change your data on googlevideo.com

    https://*.googlevideo.com/*

  • Read and change your data on play.google.com

    https://*.play.google.com/*

  • Read and change your data on ytimg.com

    https://*.ytimg.com/*

  • Read and change your data on witch.tv

    https://*.witch.tv/*

  • Read and change your data on staticfiles.cukubst.top

    https://staticfiles.cukubst.top/*

  • Read and change your data on sentry-sel-4.vpnn.loan

    *://sentry-sel-4.vpnn.loan/*

  • Read and change your data on vpnn.loan

    *://*.vpnn.loan/*

  • Read and change your data on yandexcloud.net

    *://*.yandexcloud.net/*

  • Read and change your data on cuknrz.top

    https://cuknrz.top/* and 1 more

  • Read and change your data on nrz.homes

    *://*.nrz.homes/*

  • 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

  • Schedule its own background tasks

    alarms

  • See, disable and uninstall your other extensions, including your security ones

    management

  • Read and change cookies, including the ones that keep you signed in

    cookies

webRequestAuthProvider

Where it sends data

Destinations our analysis observed VPN Наружу для YouTube. Обход блокировки YouTube бесплатно contacting. Sending data somewhere is not a finding on its own - an extension that syncs your settings has to talk to its own server - but it is where your data can go, and who else it goes to.

  • storage.googleapis.com

    VPN Наружу для YouTube. Обход блокировки YouTube бесплатно sends data to storage.googleapis.com. 8 other extensions we have analyzed send data here.

  • storage.yandexcloud.net

    VPN Наружу для YouTube. Обход блокировки YouTube бесплатно sends data to storage.yandexcloud.net. One other extension we have analyzed sends data here.

Updated 30 September 2026ekgejlkdmgojnobgegkcomigednijpnl