T05 · Unauthorized Access and Privilege Escalation
- Location
fetch_and_save.js:73- Finding
Overprivileged Access to an Existing Local Browser Session
- Content
View full analysis
Vulnerability Details
File Location:
fetch_and_save.js, lines 73–79
Vulnerability Type: Excessive browser-session privileges and unsafe fallback to an arbitrary tab
Risk Level: MediumVulnerable Code
js const browser = await puppeteer.connect({ browserURL: 'http://localhost:9222' }); const pages = await browser.pages(); const page = pages.find(p => p.url().includes('finance.sina.com.cn/7x24')) || pages[0]; await new Promise(r => setTimeout(r, 2000)); const news = await page.evaluate(() => {Technical Analysis
The script attaches Puppeteer to an already running, debugging-enabled browser rather than creating an isolated browser context. This gives the script access to every page exposed through that browser's Chrome DevTools Protocol session, including pages containing authenticated or sensitive user content.
The requested financial-news page is selected using a substring comparison. More importantly, if no matching page exists, the expression falls back to
pages[0]. The script then executespage.evaluate()in that unrelated page and queries broad selectors such as.time,.txt, and partial class-name matches. This violates least privilege because public financial-news retrieval does not require access to the user's existing browser session. The documented primary workflow already retrieves the news throughfetch_api.jswithout browser access.No evidence was found that the captured content is transmitted to an external party. However, matching text from the selected page can be stored locally in
data/news_db.json.Attack Path
- A user starts Chrome or Chromium with remote debugging enabled on port
9222. - The browser contains authenticated or otherwise sensitive open tabs.
- The user invokes
fetch_and_save.js. - The script connects to the existing DevTools session and enumerates all open pages.
- If no URL contains
finance.sina.com.cn/7x24, the script silently selects the first page. - `page.e ...[truncated 862 chars]
- A user starts Chrome or Chromium with remote debugging enabled on port
- Remediation
View remediation
Remediation Suggestions
- Remove
fetch_and_save.jsif it is obsolete, and retain only the documented HTTPS API workflow infetch_api.js. - If browser automation remains necessary, launch a dedicated browser instance or isolated browser context rather than connecting to the user's existing browser profile.
- Navigate the isolated page directly to an exact allowlisted HTTPS URL.
- Remove the
|| pages[0]fallback and fail closed if the expected page is unavailable. - Validate the page origin before calling
page.evaluate(). Require the exact expected hostname and protocol rather than a URL substring. - Narrow the DOM selectors to selectors unique to the expected news page.
- Avoid exposing Chrome DevTools on a reusable user profile. Bind it only to loopback, use a temporary profile, and terminate the isolated browser after collection.
- Add tests confirming that the script refuses to operate on unrelated tabs and cannot read from an existing authenticated session.
- Remove
