garrytan/gstack · error · Error

JS execution blocked: current page (${hostname}) does not ma

Error message

JS execution blocked: current page (${hostname}) does not match any cookie-imported domain. Imported cookies for: ${[...importedDomains].join(', ')}. This prevents cross-origin cookie exfiltration. Navigate to an imported domain or run without imported cookies.

What it means

Thrown by assertJsOriginAllowed when cookies have been imported for specific domains and the current page's hostname does not match any imported domain. This blocks js/eval execution on untrusted pages to prevent cross-origin cookie exfiltration via document.cookie. The check is bypassed only when no cookies have been imported, or when the page is about:blank / a data: URI.

Source

Thrown at browse/src/read-commands.ts:203

function assertJsOriginAllowed(bm: BrowserManager, pageUrl: string): void {
  if (!bm.hasCookieImports()) return;

  let hostname: string;
  try {
    hostname = new URL(pageUrl).hostname;
  } catch {
    return; // about:blank, data: URIs — allow (no cookies at risk)
  }

  const importedDomains = bm.getCookieImportedDomains();
  const allowed = [...importedDomains].some(domain => {
    // Exact match or subdomain match (e.g., ".github.com" matches "api.github.com")
    const normalized = domain.startsWith('.') ? domain : '.' + domain;
    return hostname === domain.replace(/^\./, '') || hostname.endsWith(normalized);
  });

  if (!allowed) {
    throw new Error(
      `JS execution blocked: current page (${hostname}) does not match any cookie-imported domain. ` +
      `Imported cookies for: ${[...importedDomains].join(', ')}. ` +
      `This prevents cross-origin cookie exfiltration. Navigate to an imported domain or run without imported cookies.`
    );
  }
}

export async function handleReadCommand(
  command: string,
  args: string[],
  session: TabSession,
  bm?: BrowserManager,
): Promise<string> {
  const page = session.getPage();
  // Frame-aware target for content extraction
  const target = session.getActiveFrameOrPage();

  switch (command) {

View on GitHub (pinned to 94993f7401)

Solutions

  1. Navigate to a page under an imported domain before running js
  2. Import cookies for the additional domain (use .domain.com form to cover subdomains)
  3. Run without imported cookies if cross-origin exfiltration is not a concern for this flow
  4. Check the current URL: `browse js location.href` is itself blocked, so inspect via the text/links commands first

Example fix

// before: cookies imported for github.com, page is on evil.com
browse js 'document.cookie'   // throws

// after: navigate to an imported domain first
browse navigate https://github.com
browse js 'document.cookie'
Defensive patterns

Strategy: try-catch

Validate before calling

function isOriginAllowed(pageUrl: string, importedDomains: Set<string>): boolean {
  let hostname: string;
  try { hostname = new URL(pageUrl).hostname; }
  catch { return true; } // about:blank, data: URIs are allowed
  if (importedDomains.size === 0) return true; // no imports → no restriction
  return [...importedDomains].some(domain => {
    const normalized = domain.startsWith('.') ? domain : '.' + domain;
    return hostname === domain.replace(/^\.//, '') || hostname.endsWith(normalized);
  });
}

// before running js
if (bm.hasCookieImports() && !isOriginAllowed(page.url(), bm.getCookieImportedDomains())) {
  throw new Error(`Refusing js on ${page.url()}: not an imported domain. Navigate first.`);
}

Type guard

function isAllowedHostname(hostname: string, importedDomains: Set<string>): boolean {
  return [...importedDomains].some(domain => {
    const normalized = domain.startsWith('.') ? domain : '.' + domain;
    return hostname === domain.replace(/^\.//, '') || hostname.endsWith(normalized);
  });
}

Try / catch

try {
  await runJs(expr);
} catch (e: any) {
  if (/JS execution blocked/.test(e.message)) {
    // navigate to an imported domain, then retry
    const target = [...bm.getCookieImportedDomains()][0].replace(/^\./, '');
    await browse.navigate(`https://${target}`);
    await runJs(expr);
  } else throw e;
}

Prevention

When it happens

Trigger: After importing cookies for github.com, running `browse js ...` while the page is on a different hostname (e.g., evil.com, an OAuth redirect page, a login portal). bm.hasCookieImports() is true, the page hostname does not match any imported domain exactly or as a subdomain.

Common situations: Agent navigated through an OAuth/SSO redirect that crosses origins; testing flow legitimately spans multiple domains but cookies were imported for only one; forgot to import cookies for a subdomain (e.g., imported github.com but page is on api.github.com without the .github.com wildcard); landed on a phishing/interstitial page.

Related errors


AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12). Data as JSON: /api/errors/21eecc1eeb48c9ce. Report an issue: GitHub.