diff --git a/src/network-services-pentesting/pentesting-web/electron-desktop-apps/README.md b/src/network-services-pentesting/pentesting-web/electron-desktop-apps/README.md index 1b3db9f3ff2..eaa31dcb7ec 100644 --- a/src/network-services-pentesting/pentesting-web/electron-desktop-apps/README.md +++ b/src/network-services-pentesting/pentesting-web/electron-desktop-apps/README.md @@ -467,6 +467,62 @@ Related reading on postMessage trust issues: ../../../pentesting-web/postmessage-vulnerabilities/README.md {{#endref}} + +## VS Code / github.dev: synthetic webview shortcuts + declarative extension command bridges + +A different VS Code webview escape class appeared in June 2026: **untrusted JavaScript inside a notebook/preview webview could synthesize privileged global shortcuts** because the webview preload forwarded `keydown` data to the host workbench and the host handled it as real user input. + +### Boundary failure + +If a cross-origin/sandboxed webview copies attacker-controlled keyboard fields (`key`, `code`, `keyCode`, modifiers, `repeat`) into a privileged `postMessage`/message-port bridge **without checking `event.isTrusted`**, JavaScript inside the webview can execute workbench shortcuts with: + +```javascript +window.dispatchEvent( + new KeyboardEvent("keydown", { + key: "a", + code: "KeyA", + keyCode: 65, + ctrlKey: true, + shiftKey: true, + }) +) +``` + +This is especially useful when **synthetic typing is blocked** by the browser. Scripted key events usually **cannot type arbitrary text into HTML `` elements**, but they still trigger shortcuts that consume `keydown` directly. + +### Practical abuse patterns + +- **Shortcut-oriented UI abuse:** target global bindings such as notification acceptance, palette navigation, focused-button activation, or menu movement instead of trying to type commands. +- **Predictable privileged prompts from workspace metadata:** a repository-controlled `.vscode/extensions.json` can recommend an attacker extension and create a predictable install notification that can be accepted with a shortcut such as `Ctrl+Shift+A`. +- **Declarative extension manifest as command bridge:** even if local workspace extension code is blocked by CSP in web VS Code, declarative `package.json` contributions may still load. A local extension under `.vscode/extensions` can register a keybinding that calls `runCommands` and then a privileged internal command such as `workbench.extensions.installExtension`. + +Example manifest pattern: + +```json +{ + "contributes": { + "keybindings": [{ + "key": "ctrl+f1", + "command": "runCommands", + "args": {"commands": [{ + "command": "workbench.extensions.installExtension" + }]} + }] + } +} +``` + +- **Hidden security flags reachable from untrusted metadata:** if the internal command accepts attacker-controlled arguments like `{"context":{"skipPublisherTrust":true}}`, declarative metadata can suppress a trust dialog and install a Marketplace/CDN-hosted extension that finally executes attacker code. +- **Trusted-workspace abuse:** if remote/web workspaces are auto-trusted, local workspace extensions become a high-value bridge from repository content to privileged editor actions. +- **Post-compromise scope amplification:** after extension execution, inspect what tokens the editor exposes to extensions. In `github.dev`, the stolen GitHub token was valid beyond the opened repository, so querying `https://api.github.com/user/repos` enumerated additional accessible private repositories. + +### Audit notes + +- Treat **webview-to-host input forwarding** as a privilege boundary; never re-dispatch synthetic key/click events from untrusted frames into the host. +- Enforce authorization **inside** sensitive commands. Do not accept caller-provided command context that can set internal flags such as `skipPublisherTrust`. +- Do not assume blocking executable local extension code is enough; also review **declarative contributions** (`keybindings`, `menus`, `commands`, tasks) from workspace-controlled manifests. +- The June 3, 2026 fixes added `isTrusted` to forwarded events, disabled untrusted key forwarding in notebook webviews, and stopped accepting caller-supplied install-command context. + ## Post-exploitation: ASAR/main-process implants If you obtain **write access** to an Electron app resources directory, a very practical post-exploitation primitive is to **patch `app.asar`** (or the JS entrypoint it loads) and wait for the user to relaunch the app. Unlike a renderer-only XSS, code loaded from the **main process** executes in the app's **Node.js runtime**, so it can usually access the **filesystem**, spawn commands, hook Electron APIs, and inspect authenticated application state. @@ -663,5 +719,10 @@ Detection and mitigations - More researches and write-ups about Electron security in [https://github.com/doyensec/awesome-electronjs-hacking](https://github.com/doyensec/awesome-electronjs-hacking) - [https://www.youtube.com/watch?v=Tzo8ucHA5xw\&list=PLH15HpR5qRsVKcKwvIl-AzGfRqKyx--zq\&index=81](https://www.youtube.com/watch?v=Tzo8ucHA5xw&list=PLH15HpR5qRsVKcKwvIl-AzGfRqKyx--zq&index=81) - [https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html) +- [One-Click GitHub Token Theft via VS Code Webview Keyboard Event Injection](https://blog.ammaraskar.com/github-token-stealing) +- [VS Code issue #319593: Webviews can trigger arbitrary keyboard shortcuts in the main workbench](https://github.com/microsoft/vscode/issues/319593) +- [VS Code PR #319705: confirm notebook opening and stop accepting caller-provided installExtension context](https://github.com/microsoft/vscode/pull/319705) +- [VS Code PR #319813: block programmatic webview keypress/click re-dispatch in notebook webviews](https://github.com/microsoft/vscode/pull/319813) +- [VS Code 1.89 / local workspace extensions](https://code.visualstudio.com/updates/v1_89#_local-workspace-extensions) {{#include ../../../banners/hacktricks-training.md}}