A critical security vulnerability in Visual Studio Code’s webview implementation allows attackers to steal GitHub OAuth tokens, including read/write access to private repositories, simply by tricking a victim into clicking a single malicious link.

The bug was publicly disclosed on June 2, 2026, by security researcher Ammar Askar, who opted for full disclosure after prior negative experiences with Microsoft’s Security Response Center (MSRC).

GitHub offers a browser-based, lightweight VSCode editor accessible at github.dev. When a user navigates from github.com to github.dev on any repository, github.com automatically POSTs an OAuth token to the github.dev session that grants full access to every repository the user has access to not just the one they opened.

This unscoped token, combined with the nearly full VSCode TypeScript codebase running in-browser, creates an attractive target for attackers.

VSCode’s Webview Security Model

VSCode isolates potentially untrusted content using webviews

This cross-origin isolation prevents webview JavaScript from directly calling VSCode’s Node.js or editor APIs. Features like Markdown previews and Jupyter notebook outputs all render inside these sandboxed iframes.

VS Code uses the Window.postMessage() API (Source: Ammar Askar)

To allow the editor and webviews to communicate for example, to sync a Markdown preview with the current editor line VSCode uses the Window.postMessage() API, passing structured JavaScript objects between the two isolated origins.

To improve user experience, VSCode’s webview implementation registers a did-keydown event handler that forwards every keyboard event from inside the webview to the main VSCode window via postMessage. This allows keyboard shortcuts like Ctrl+Shift+P to function seamlessly even when a user is focused inside a webview.

Untrusted JavaScript in a webview can create fake keydown events, simulating user keyboard input. The security boundary meant to separate “Dangerous APIs” from “Untrusted User Content” is compromised, as the postMessage channel for keyboard forwarding unintentionally links them.

security boundary for webviews (Source: Ammar Askar)

Exploit Chain: From Click to Token Exfiltration

Security researcher Ammar Askar published a full proof-of-concept on June 2, 2026, demonstrating a complete token-steal exploit chain. The attack leverages five chained VSCode behaviors:

Jupyter Notebook can be exploited through malicious .ipynb files that utilize an HTML image tag with an onerror handler to execute arbitrary JavaScript within a webview iframe. Similarly, in Visual Studio Code (VSCode), attackers can leverage the .vscode/extensions.json file, which typically recommends extensions.

The payload waits for a recommendation notification from VSCode and then dispatches a synthetic Ctrl+Shift+A keydown event, which corresponds to the “Notifications: Accept Notification Primary Action” command, enabling silent installation of the malicious extension.

Instead of installing from the Marketplace where a publisher trust dialog would be triggered—the attacker can place the harmful extension directly in the .vscode/extensions/ directory.

This method allows the extension to bypass the trusted publisher check, relying solely on workspace trust, a characteristic that makes github.dev workspaces always trusted. Due to restrictions imposed by Content Security Policies, local extensions cannot load their worker scripts from anywhere but vscode-cdn.net.

To overcome this limitation, the attacker can introduce a custom keybinding (such as Ctrl+F1) through package.json, which calls the workbench.extensions.installExtension function while setting skipPublisherTrust to true.

Once installed, the malicious extension can access the preloaded GitHub OAuth token and make requests to https://api.github.com/user/repos to enumerate all accessible private repositories, ultimately exfiltrating both the token and the list of repositories.

Javascript payload (Source: Ammar Askar)

The full JavaScript payload executes in well under a minute and requires zero interaction beyond the initial link click.

Javascript payload runs (Source: Ammar Askar)

The vulnerability affects github.dev, the browser-hosted VSCode, as well as the desktop version of VSCode, though the desktop variant requires the victim to clone and open the attacker’s repository.

On desktop, a successful exploit achieves full Remote Code Execution (RCE) since VSCode extensions have unrestricted access to Node.js APIs, including child_process.

The stolen GitHub OAuth token is not scoped to a single repository, meaning an attacker could silently read, modify, or push to every private repository a victim has access to.

Since github.dev does not implement CSRF tokens, any link on the internet can redirect a user into this attack. Mitigation steps include:

  • Clear site data for github.dev in your browser (Chrome: URL bar icon → Cookies and site data → Manage on-device site data → delete all github.dev domains). This re-enables a warning dialog, giving users a chance to navigate away.
  • Avoid clicking unknown github.dev links until a patch is issued by Microsoft or GitHub.
  • Audit installed extensions on github.dev and uninstall anything unrecognized.
  • Users who have never visited github.dev before and have cleared their local storage are protected by an initial consent dialog.

The researcher acknowledged that VSCode’s defense-in-depth measures limited the blast radius. The strict Content Security Policy (script-src ‘none’) on extension Markdown preview pages blocks arbitrary JavaScript execution there, preventing an even simpler 1-click RCE path via a malicious Marketplace extension page. The use of DOMPurify for sanitizing rendered Markdown also closes off cross-site scripting vectors.

Researcher Ammar Askar published this vulnerability as a full public disclosure with no prior coordinated notice to Microsoft, citing a prior negative experience with the Microsoft Security Response Center (MSRC). Askar notified a GitHub security contact one hour before posting.