1-Click GitHub Token Stealing via a VSCode Bug

Author: Ammar Askar
Published: June 2, 2026
Source: https://blog.ammaraskar.com/github-token-stealing/

Summary

A security researcher discovered a critical vulnerability in VSCode’s webview security model that allows an attacker to steal a victim’s GitHub authentication token — which carries full access to all of their repositories — through a single malicious link. The attack targets github.dev, GitHub’s browser-based VSCode instance, and exploits a flaw in how VSCode handles keyboard events bubbled out of sandboxed webview iframes. Because the OAuth token issued to github.dev is not scoped to a specific repository, successful exploitation grants an attacker read and write access to every repository the victim can access.

Technical Details

VSCode isolates webview content in sandboxed iframes served from a separate origin (vscode-webview://), with cross-frame communication handled through Window.postMessage(). However, the notebook renderer registers a did-keydown event listener that forwards keyboard events from the webview frame to the main VSCode window without validating the event origin. This means JavaScript running inside an untrusted webview can dispatch synthetic KeyboardEvent objects that VSCode treats as genuine user keystrokes.

The full exploitation chain proceeds as follows:

  1. Initial payload delivery: A malicious Jupyter Notebook (README.ipynb) is hosted in a public repository. Its markdown cells contain <img> tags with onerror handlers that execute JavaScript when the notebook is rendered in github.dev.
  2. Synthetic keydown events: The JavaScript fires crafted KeyboardEvent sequences (e.g., Ctrl+Shift+A, Ctrl+F1) that bubble through the unguarded did-keydown listener into the main VSCode process.
  3. Workspace extension sideloading: The repository includes a local workspace extension under .vscode/extensions/. The synthetic keystrokes invoke workbench.extensions.installExtension with skipPublisherTrust: true, bypassing VSCode’s publisher trust verification and installing the bundled extension without user approval.
  4. Token exfiltration: The installed extension accesses the in-memory GitHub OAuth token and queries the GitHub REST API (https://api.github.com/user/repos), exposing a list of all private repositories accessible to the victim. The token can be exfiltrated to an attacker-controlled server.

The researcher notes that VSCode’s Content Security Policy (script-src 'none') and DOMPurify sanitization in rendered markdown provided meaningful defense-in-depth that limited certain attack surfaces, though they were ultimately bypassed through the onerror vector in image tags combined with the unguarded keyboard event channel.

A similar attack path exists against VSCode Desktop, though exploitation is harder because it requires the victim to clone the repository first.

No CVE identifier has been publicly assigned at the time of writing. The vulnerability was reported via the VSCode issue tracker as issue #319593.

Impact

A victim who opens a maliciously crafted public repository in github.dev exposes a GitHub OAuth token with full, unscoped write access to every repository they can access — including private repositories across personal accounts and any organizations they are a member of. An attacker can use the stolen token to read, clone, or modify private source code, inject malicious commits, access secrets stored in repositories, or leverage repository access to pivot into CI/CD pipelines and cloud infrastructure.

Mitigation

Microsoft shipped two fixes on June 3, 2026:

  • Stopgap fix (PR #319705): Added confirmation dialogs when opening notebooks in web VSCode and blocked the skipPublisherTrust bypass via keyboard-triggered commands.
  • Complete fix (PR #319813): Prevented keydown events from bubbling out of notebook webviews entirely, eliminating the synthetic keystroke attack vector.

Users who opened untrusted repositories in github.dev before June 3, 2026 should take the following steps:

  1. Clear cookies and local storage for github.dev in their browser settings.
  2. Delete all site data for github.dev domains.
  3. Audit and uninstall any unfamiliar extensions installed through github.dev.
  4. Consider rotating GitHub personal access tokens and reviewing OAuth app authorizations at github.com/settings/applications.

References

Leave a Comment