Is VPN для ChatGPT safe?

High risk

VPN для ChatGPT is high risk. Opening the popup fetches a config file from GitHub Pages, then Blogspot, then Google Docs as fallbacks, ROT-3 shifted and parsed as JSON. A 'u' value replaces the API host; an 's' value replaces the proxy list.

sherechevskiyv5.5Chrome Web Store
75Risk

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

Publishers can request a review.

Findings

SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-829
SourceAI SANDBOX

Backend API and proxy list pulled from GitHub Pages and overwritten at runtime

Opening the popup fetches a config file from GitHub Pages, then Blogspot, then Google Docs as fallbacks, ROT-3 shifted and parsed as JSON.

A 'u' value replaces the API host; an 's' value replaces the proxy list.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You open the extension popup.

The extension did this

The extension fetches a config file from an external GitHub Pages page (Blogspot/Google Docs fallbacks), decodes it, and overwrites its backend API host and proxy list.

The new backend host is written to local storage, so it persists across sessions until changed again by a later fetch.

02EvidenceNETWORK CAPTURE
Captured request
GEThttps://s-extension.github.io/DataExst/data.json
Observed during dynamic analysis when the popup opened: a ~4.6 KB response body, ROT-3 encoded. After decoding, it contained a backend host override and roughly 65 proxy server entries that were not present in the extension's shipped js/conf.js.
03EvidenceOPAQUE REVEAL
Why you can't catch this in DevTools

The fetched config is shifted with a ROT-3 letter cipher before it is published, so the raw response is not directly readable. Shifting each letter back by three positions reveals normal JSON naming a backend host and proxy entries.

What's actually being sent
{"u":"obratx.shop", "s":[ /* ~65 base64-encoded proxy entries; each decodes to host:port:user:pass|expiry|country|tag, e.g. 168.81.75.126:9091:tFC47N:BDpmJp|2026-07-14|in|rmd */ ]}
04EvidenceCODE COMPARE
The code that does this

The fetch-decode-override path, from the shipped source.

What it actually does
What the decode-and-override logic does
// On popup open: fetch the remote config, decode it, apply overrides.
function applyRemoteConfig(rawBody) {
  const json = JSON.parse(rot3Decode(rawBody.trim()));   // showx(body, 3)
  if (json.u && json.u.length > 0) {
    backendApi = 'https://' + json.u;                    // overwrite api.hhos.ru
    chrome.storage.local.set({ apiurl: json.u });        // persist across sessions
  }
  if (json.s) {
    chrome.storage.local.set({ servers: JSON.stringify(json.s) }); // replace proxy list
    rebuildServerList(json.s);
  }
}
05EvidenceTHIRD PARTY LIST
Hosts involved in remote config delivery and the resulting backend:
  • s-extension.github.io

    Primary config source. Serves DataExst/data.json (ROT-3 encoded) used to override the backend host and proxy list. Hosted on GitHub Pages.

  • dtxtension.blogspot.com

    Fallback config source. Config read from a .post-body paragraph on the page. Hosted on Google Blogspot.

  • docs.google.com

    Fallback config source. Config read from a DOCS_modelChunk script block in a Google Docs document.

  • api.hhos.ru

    Default bundled backend host, used until a fetched config supplies a 'u' value that replaces it.

06EvidenceARTIFACT
Reproduce it yourself

Fetches the extension's remote config from GitHub Pages, applies the ROT-3 decode the extension uses, and prints the backend host override ('u') and proxy entries ('s'). Lets you confirm what the external file currently instructs the extension to do.

RequiresNode.js 18+ (global fetch)
decode-remote-config.js · js
// decode-remote-config.js
// Usage: node decode-remote-config.js
const URL = 'https://s-extension.github.io/DataExst/data.json';
function rot3(text) {
  return text.split('').map(ch => {
    if (/[a-z]/i.test(ch)) {
      const code = ch.charCodeAt(0);
      const base = code >= 65 && code <= 90 ? 65 : 97;
      return String.fromCharCode(((code - base - 3 + 26) % 26) + base);
    }
    return ch;
  }).join('');
}
(async () => {
  const raw = await (await fetch(URL)).text();
  const json = JSON.parse(rot3(raw.trim()));
  if (json.u) console.log('Backend host override (u):', 'https://' + json.u);
  if (Array.isArray(json.s)) {
    console.log(`Proxy entries (s): ${json.s.length}`);
    for (const e of json.s.slice(0, 5)) {
      console.log('  ', Buffer.from(e, 'base64').toString('utf8'));
    }
  }
})();
How to run it
  1. 1
    Save this file.
  2. 2
    Run: node decode-remote-config.js.
  3. 3
    Read the printed backend host override and the first few decoded proxy entries. Re-run later to see whether the externally-hosted config has changed.
Updated 17 September 2026mcbbkppinglngggemoflhaajipkapgml