feat: GStack Browser stealth + branding — anti-bot patches, custom UA, rebrand

- Add GSTACK_CHROMIUM_PATH env var for custom Chromium binary
- Add BROWSE_EXTENSIONS_DIR env var for extension path override
- Move auth token to /health endpoint (fixes read-only .app bundles)
- Anti-bot stealth: disable navigator.webdriver, fake plugins, languages
- Custom user agent: Chrome/<version> GStackBrowser (auto-detects version)
- Rebrand Chromium plist to "GStack Browser" at launch time
- Update security test to match new token-via-health approach
This commit is contained in:
Garry Tan
2026-03-30 20:47:00 -07:00
parent 18d6e10dbc
commit 126cebf4c4
4 changed files with 137 additions and 27 deletions
+7 -2
View File
@@ -34,8 +34,13 @@ function getBaseUrl() {
async function loadAuthToken() {
if (authToken) return;
// Get token from browse server /health endpoint (localhost-only, safe).
// Previously read from .auth.json in extension dir, but that breaks
// read-only .app bundles and codesigning.
const base = getBaseUrl();
if (!base) return;
try {
const resp = await fetch(chrome.runtime.getURL('.auth.json'));
const resp = await fetch(`${base}/health`, { signal: AbortSignal.timeout(3000) });
if (resp.ok) {
const data = await resp.json();
if (data.token) authToken = data.token;
@@ -88,7 +93,7 @@ function setConnected(healthData) {
function setDisconnected() {
const wasConnected = isConnected;
isConnected = false;
// Keep authToken — it comes from .auth.json, not /health
// Keep authToken — it persists across reconnections
chrome.action.setBadgeText({ text: '' });
chrome.runtime.sendMessage({ type: 'health', data: null }).catch(() => {});