T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- scripts/gemini-webapi/utils/load-browser-cookies.ts:101
- Finding
- Existing Chrome Debugging Sessions Are Reused to Extract Google Authentication Cookies<![CDATA[ ## Vulnerability Details **File Location**: `scripts/gemini-webapi/utils/load-browser-cookies.ts:101-163` and `scripts/gemini-webapi/utils/load-browser-cookies.ts:263-271` **Vulnerability Type**: Existing browser-session credential extraction beyond least privilege **Risk Level**: High ### Vulnerable Code ```ts async function fetch_cookies_from_existing_chrome( timeoutMs: number, verbose: boolean, ): Promise<CookieMap | null> { const discovered = await discoverRunningChromeDebugPort(); if (discovered === null) return null; if (verbose) logger.info(`Found reusable Chrome debugging session on port ${discovered.port}. Connecting via WebSocket...`); let cdp: CdpConnection | null = null; let targetId: string | null = null; let createdTarget = false; try { const connectStart = Date.now(); const connectTimeout = 30_000; let lastConnErr: unknown = null; while (Date.now() - connectStart < connectTimeout) { try { cdp = await CdpConnection.connect(discovered.wsUrl, 5_000); break; } catch (e) { lastConnErr = e; if (verbose) logger.debug(`WebSocket connect attempt failed: ${e instanceof Error ? e.message : String(e)}, retrying...`); await sleep(1000); } } if (!cdp) { if (verbose) logger.debug(`Could not connect to Chrome after ${connectTimeout / 1000}s: ${lastConnErr instanceof Error ? lastConnErr.message : String(lastConnErr)}`); return null; } const page = await openPageSession({ cdp, reusing: false, url: GEMINI_APP_URL, matchTarget: (target) => target.type === 'page' && target.url.includes('gemini.google.com'), enableNetwork: true, activateTarget: false, }); const { sessionId } = page; targetId = page.targetId; createdTarget = page.createdTarget; if (verbose) logger.debug(createdTarget ? 'No Gemini tab found, creating new tab...' : 'Found existing Gemini tab, attaching...'); con ...[truncated 3448 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Use a dedicated Chrome profile by default and remove automatic discovery of ordinary browser profiles. 2. Require explicit, immediate user authorization before attaching to an existing browser debugging session. 3. Make existing-session reuse an opt-in command-line option rather than the default fallback. 4. Allowlist only the cookie names strictly required for Gemini authentication, such as the specifically documented session cookies. 5. Do not retain unrelated Google cookies returned by `Network.getCookies`. 6. Clearly display the browser profile and domains that will be accessed before connecting. 7. Fail closed if the discovered WebSocket URL is not loopback-bound or does not correspond to the expected Chrome instance. ]]>
