AI and data stack advisories

Severe, 6 weeks1496Projects326

1496 severe, 6 weeks · 326 projects

GoogleGHSA-vx62-cvr5-x3p4

Cross-Frame Scripting (XFS) via Background Proxy in Vimium

Google

Published Sep 1, 2026

Medium
Fix: upgrade to 2.4.3 or later
GitHub advisory

Summary

Vimium's background script provides an openUrlInCurrentTab message handler that allows content scripts to request a URL to be opened in the current tab. When a javascript: URL is provided, the background script uses the chrome.scripting.executeScript API to inject and execute the code.

However, the background script does not specify a frameId in the injection target. According to the Chrome Extension API documentation for Manifest V3, if frameId is omitted, the script is injected into the main frame by default.

Since any frame (including cross-origin iframes) where Vimium is active can send this message to the background script, a compromised content script in a low-privilege subframe can execute arbitrary JavaScript in the high-privilege top-level origin.

Vulnerability Detail

  • Vulnerability Type: Cross-Frame Scripting (XFS) / Privilege Escalation
  • Affected Component: background_scripts/tab_operations.js
  • Affected Versions: Up to 2.4.2 (Manifest V3)

Severity

Medium - This is a medium-severity privilege escalation vulnerability. It does not provide an initial entry point for an attack, but it can be used to significantly increase the impact of a separate, hypothetical DOM-based XSS flaw within Vimium. If an attacker achieves code execution within a subframe's Vimium context, this flaw allows them to escalate those...

Affected versions

PackageAffectedFixed in
Vimium
Product
< 2.4.32.4.3
Details and references

### Summary Vimium's background script provides an `openUrlInCurrentTab` message handler that allows content scripts to request a URL to be opened in the current tab. When a `javascript:` URL is provided, the background script uses the `chrome.scripting.executeScript` API to inject and execute the code. However, the background script does not specify a `frameId` in the injection target. According to the Chrome Extension API documentation for Manifest V3, if `frameId` is omitted, the script is injected into the **main frame** by default. Since any frame (including cross-origin iframes) where Vimium is active can send this message to the background script, a compromised content script in a low-privilege subframe can execute arbitrary JavaScript in the high-privilege top-level origin. ### Vulnerability Detail - **Vulnerability Type:** Cross-Frame Scripting (XFS) / Privilege Escalation - **Affected Component:** `background_scripts/tab_operations.js` - **Affected Versions:** Up to 2.4.2 (Manifest V3) ### Severity Medium - This is a medium-severity privilege escalation vulnerability. It does not provide an initial entry point for an attack, but it can be used to significantly increase the impact of a separate, hypothetical DOM-based XSS flaw within Vimium. If an attacker achieves code execution within a subframe's Vimium context, this flaw allows them to escalate those privileges to the top-level origin, potentially leading to Cross-Site Scripting (XSS) on the parent page. ### Proof of Concept The vulnerable code is located in `background_scripts/tab_operations.js`: ```javascript export async function openUrlInCurrentTab(request) { const urlStr = await UrlUtils.convertToUrl(request.url); // ... if (UrlUtils.hasJavascriptProtocol(urlStr)) { const scriptingArgs = { target: { tabId: request.tabId }, // VULNERABILITY: Omitted frameId func: (text) => { ... }, args: [urlStr], }; // ... chrome.scripting.executeScript(scriptingArgs); } } ``` The `request` object is populated from the `sender` in `background_scripts/main.js`, but `sender.frameId` was previously ignored during the injection phase. ## Reproduction Steps 1. Navigate to a website that embeds a cross-origin iframe (e.g., a page with a YouTube embed or a third-party ad). 2. Open **Chrome DevTools** (`F12`). 3. Go to the **Console** tab. 4. Click the **Execution Context selector** (the dropdown in the top-left of the console, usually showing `top`). 5. Find the entry for the **cross-origin iframe** and select the **Vimium** extension context associated with it (it will be listed under the extension's name). 6. Execute the following payload in the console: ```javascript chrome.runtime.sendMessage({ handler: "openUrlInCurrentTab", url: "javascript:alert('XFS Success! Target Origin: ' + window.location.origin + '\\nLogged from: ' + document.origin)", }); ``` 7. **Success Condition**: An alert dialog will appear. Observe that `window.location.origin` reflects the **top-level page's origin**, proving that the script was successfully proxied from the iframe into the parent frame. ### Further Analysis The background script must explicitly target the frame that originated the request. **Fix:** In `background_scripts/main.js`, `sender.frameId` is captured and passed to the handler. In `background_scripts/tab_operations.js`, the `frameId` is included in the `target` object: ```javascript target: { tabId: request.tabId, frameIds: [request.frameId] } ``` ### Timeline **Date reported**: 2026-07-17 **Date fixed**: 2026-07-22 **Date disclosed**: 2026-09-01 https://github.com/philc/vimium/commit/4427dc6783503c90b5975876f8547588d33c8ee7

Severity from
GitHub (reviewed advisory)

More Google advisories

All Google