Is Proxy Switcher safe?
Proxy Switcher can route Chrome traffic through a hardcoded proxy when its Test Proxy button is clicked.
When the popup's Test Proxy button is clicked, the extension writes a hardcoded proxy host, port, username, and password into Chrome's proxy settings. Non-local browser traffic is then routed through 192.147.177.75:50100, with the extension answering proxy authentication challenges using the embedded credentials.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Proxy test button routes Chrome traffic through a fixed proxy
Clicking the popup's Test Proxy button saves a fixed proxy config and applies it to Chrome browsing.
The endpoint 192.147.177.75:50100 can then receive routed requests, including destination URLs, headers, and network address.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-506
- Source
- Dynamic sandbox
You click the Test Proxy button in the extension popup.
The button is visible next to Clear Proxy in the popup UI.
The extension saves a fixed proxy configuration and turns the proxy on for regular Chrome traffic.
The saved endpoint is 192.147.177.75:50100 with the username rutracker1999.
These saved settings tell Chrome which proxy endpoint to use after the popup test button is clicked.
- Location
- chrome.storage.local proxy settings
{ "proxyHost": "192.147.177.75", "proxyPort": "50100", "proxyScheme": "https", "proxyPassword": "WSUmNmL8wz", "proxyUsername": "rutracker1999"}- Destination URLshttps://example.com/account (illustrative)
The proxy can see which sites and paths your browser requests when traffic is routed through it.
- Request headersUser-Agent: Mozilla/5.0 Chrome/126.0 (illustrative)
Headers can reveal browser context such as referrers, cookies for the destination site, and user-agent details.
- Connection IP address203.0.113.42 (illustrative)
The proxy can observe the network address associated with the routed browser connection.
Observed during dynamic analysis: after the Test Proxy click, browser requests were attempted through the configured proxy endpoint.
Popup code writes the proxy settings and applies them
The popup exposes a Test Proxy control
popup.html<button id="test-proxy-btn" class="test">Test Proxy</button>Readable equivalent of testProxy()
popup.jsfunction testProxy() { proxyHost.value = "192.147.177.75"; proxyPort.value = "50100"; proxyScheme.value = "https"; proxyUsername.value = "rutracker1999"; proxyPassword.value = "WSUmNmL8wz"; updateAuthFields(); chrome.storage.local.set({ proxyHost: proxyHost.value.trim(), proxyPort: proxyPort.value, proxyScheme: proxyScheme.value, proxyUsername: proxyUsername.value.trim(), proxyPassword: proxyPassword.value.trim() }, function() { chrome.runtime.sendMessage({ action: "prepareProxyAuth" }, function() { proxyToggle.checked = true; toggleProxy(true); }); });}Readable equivalent of generatePacScript()
popup.jsfunction generatePacScript(host, port, scheme, username, password) { let proxyRule = ""; if (scheme === "https") { proxyRule = `PROXY ${host}:${port}`; } else if (scheme === "http") { proxyRule = `PROXY ${host}:${port}`; } else if (scheme === "socks5") { proxyRule = `SOCKS5 ${host}:${port}`; } else if (scheme === "socks4") { proxyRule = `SOCKS ${host}:${port}`; } return "function FindProxyForURL(url, host) {\n" + " if (isPlainHostName(host) ||\n" + " shExpMatch(host, '*.local') ||\n" + " isInNet(host, '10.0.0.0', '255.0.0.0') ||\n" + " isInNet(host, '172.16.0.0', '255.240.0.0') ||\n" + " isInNet(host, '192.168.0.0', '255.255.0.0') ||\n" + " isInNet(host, '127.0.0.0', '255.0.0.0') ||\n" + " isInNet(host, '169.254.0.0', '255.255.0.0') ||\n" + " host === 'localhost') {\n" + " return 'DIRECT';\n" + " }\n" + " return '" + proxyRule + "';\n" + "}";}Readable equivalent of applyPacScript()
popup.jsfunction applyPacScript(pacScript) { return new Promise((resolve, reject) => { chrome.proxy.settings.set({ value: { mode: "pac_script", pacScript: { data: pacScript } }, scope: "regular" }, function() { if (chrome.runtime.lastError) { reject(Error(chrome.runtime.lastError.message)); return; } resolve(); }); });}Background worker supplies the saved proxy credentials
chrome.webRequest.onAuthRequired.addListener( function(details, callback) { if (!details.isProxy) { callback(); return; } return chrome.storage.local.get([ "proxyHost", "proxyPort", "proxyScheme", "proxyUsername", "proxyPassword" ], function(settings) { try { const hasCredentials = Boolean(settings && settings.proxyUsername && settings.proxyPassword); const storedHost = (settings && settings.proxyHost ? String(settings.proxyHost) : "").toLowerCase(); const storedPort = settings && settings.proxyPort != null ? String(settings.proxyPort) : ""; const challengedHost = details && details.challenger && details.challenger.host ? String(details.challenger.host).toLowerCase() : ""; const challengedPort = details && details.challenger && details.challenger.port != null ? String(details.challenger.port) : ""; if (hasCredentials && storedHost && storedPort && storedHost === challengedHost && storedPort === challengedPort) { callback({ authCredentials: { username: settings.proxyUsername, password: settings.proxyPassword } }); } else { callback(); } } catch (error) { callback(); } }); }, { urls: ["<all_urls>"] }, ["asyncBlocking"]);- 192.147.177.75
Proxy endpoint on port 50100 used for regular non-local Chrome traffic after the Test Proxy button is clicked.
Where it sends data
Destinations our analysis observed Proxy Switcher 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.
- 192.147.177.75:50100
Proxy Switcher sends data to 192.147.177.75:50100. No other extension we have analysed sends data here.