VSCodeのゼロデイでOAuthトークンがワンクリックで窃取可能-研究者がPoCを公開

セキュリティニュース

投稿日時: 更新日時:

VSCodeのゼロデイでOAuthトークンがワンクリックで窃取可能-研究者がPoCを公開

2026年6月2日、セキュリティ研究者Ammar Askarは自身のブログ「1-Click GitHub Token Stealing via a VSCode Bug」でVSCode(Visual Studio Code)のウェブビュー実装に存在するゼロデイ脆弱性を公開し、PoC(概念実証コード)を同時にリリースしました。最大のリスクは攻撃の単純さと影響範囲の広さにあります。

被害者は悪意あるGitHubリポジトリをgithub.devで開くだけでURLの変更ひとつで誰でも行う日常的な操作でそのGitHubアカウントが読み書きアクセスできる全リポジトリ(プライベートを含む)へのOAuthトークンが攻撃者に窃取されます。

この公開はサイバー犯罪グループ「TeamPCP」が悪意ある拡張機能を通じてGitHubの内部リポジトリ数千件を侵害したわずか数週間後という時期に行われました。VSCodeは開発者の認証情報・トークン・ソースコードを狙う攻撃者にとって繰り返し標的とされているエディタとなっています。

AskarはMicrosoftのSecurity Response Center(MSRC)への協調開示を意図的に行わず、GitHubのセキュリティ担当者への1時間前の通知のみでフルディスクロージャを選択しました。その理由は「MSRCへのバグ報告でクレジットも告知もなく静かに修正された」という過去の経験です。本脆弱性は記事公開時点でパッチが存在せず、CVEも未アサインです。本記事では攻撃の仕組み・影響範囲・MSRCをめぐる構造的問題・即時の対処方法を解説します。

サマリー

  • 2026年6月2日、Ammar Askarが「1-Click GitHub Token Stealing via a VSCode Bug」を公開。PoC付き、CVE未アサイン、パッチなし。GitHubへの通知は1時間前のみ
  • 公開の背景:TeamPCPがVSCode拡張機能経由でGitHub内部リポジトリを数千件侵害した直後の公開。VSCodeは認証情報・トークン窃取の繰り返し標的
  • 攻撃対象はgithub.dev——全リポジトリのread/write権限付きOAuth tokenが自動的にgithub.devセッションへ送信される設計
  • 脆弱性の核心:VSCodeウェブビューのdid-keydownイベントハンドラーが偽のkeydownイベントを区別できない設計上の欠陥
  • 悪意あるJupyter Notebookのonerrorハンドラーから5段階のチェーンで悪意ある拡張機能をインストール、OAuthトークンを窃取して全プライベートリポジトリを列挙
  • VSCodeの既存防御(CSP・DOMPurify・script-src 'none')が「最悪の事態(デスクトップRCE)」を防止
  • MSRCへの不満とフルディスクロージャ宣言:Askarは「今後VSCode脆弱性はすべてフルパブリックディスクロージャで公開する」と宣言。Nightmare Eclipse事案とも連動
  • Microsoftは無回答:The Recordの「Askarへのクレジット付与の有無・CVE未アサインの理由・影響ユーザー数」への質問に発行前に回答しなかった
  • 即時対処:ブラウザでgithub.devのCookieとサイトデータを削除することで攻撃成立の前提条件を除去できる

TeamPCPによるVSCode拡張機能侵害との連動—繰り返し標的になるVSCode

Askarの公開がTeamPCPによるGitHub侵害の直後に行われたという時系列です。

TeamPCPは、VSCode拡張機能に仕込まれた悪意あるコードを通じてGitHubの内部リポジトリ数千件を侵害したサイバー犯罪グループです。

GitHubは後に「顧客への影響はない」と発表しましたが、この事案はVSCodeのエコシステム(拡張機能・ウェブビュー・認証フロー)が開発者の認証情報・トークン・ソースコードを狙う攻撃者にとって「繰り返し標的とされる攻撃面」になっていることを改めて示しました

今回Askarが公開した脆弱性も、TeamPCPが悪用した「VSCode拡張機能経由でトークンを窃取する」という攻撃カテゴリの延長線上に位置しています。

関連:GitHubのソースコードが不正アクセスによるサイバー攻撃でダークウェブで売りに出される-TeamPCPが犯行声明

違いは、TeamPCPが拡張機能の改ざんというサプライチェーン攻撃を用いたのに対し、今回の手法は悪意ある.ipynbファイルを含むGitHubリポジトリのURLをクリックするだけでトークン窃取が完結するという点で、攻撃の難易度が飛躍的に低いことです。

github.devとは何か—なぜOAuthトークンが標的になるのか

Askarのブログによれば、github.devはGitHubが提供するブラウザベースの軽量VSCodeエディタです。

任意のGitHubリポジトリのURLのgithub.comgithub.devに書き換えるか、リポジトリのドロップダウンメニューから選択するだけで、ブラウザ内でそのリポジトリのファイル閲覧・プルリクエスト送信・コミットが可能なVSCodeが起動します。

この仕組みを実現するために、github.comgithub.devセッションに対してOAuth tokenをHTTP POSTで送信します。ここに重大な問題があります。このトークンは開いた特定のリポジトリだけにスコープされておらず、そのユーザーがアクセスできる全リポジトリへの完全な読み書き権限を持っています

さらにgithub.devはVSCodeの約100万行のTypeScriptコードベースをほぼそのままブラウザで動作させているため、VSCodeに存在する脆弱性がそのまま「フル権限トークンを窃取できる攻撃面」となります。


脆弱性の核心—did-keydownイベントフォワーディングの設計上の欠陥

Askarのブログが詳細に解説している脆弱性の技術的背景は次のとおりです。

VSCodeはセキュリティ上の理由から、マークダウンプレビューやJupyterノートブックなどの信頼できないコンテンツを<iframe>要素(vscode-webview://オリジン)でメインVSCodeウィンドウ(vscode-file://オリジン)から分離して表示します。異なるオリジン間は通常のDOM操作ができないため、両者の通信にはWindow.postMessage()APIが使われます。

ここで使い勝手の問題が発生します。ウェブビュー内にフォーカスがある状態でCtrl+Shift+P(コマンドパレット)などのVSCodeキーボードショートカットが使えなければ、ユーザー体験が著しく低下します。この問題を解決するため、VSCodeはウェブビューの読み込み時に以下のコードを実行します。

contentWindow.addEventListener('keydown', handleInnerKeydown);
const handleInnerKeydown = (e) => {
  hostMessaging.postMessage('did-keydown', {
  key: e.key, keyCode: e.keyCode, code: e.code,
  shiftKey: e.shiftKey, altKey: e.altKey,
  ctrlKey: e.ctrlKey, metaKey: e.metaKey, ...
  });
};

このコードはウェブビュー内の全keydownイベントをメインVSCodeウィンドウに転送します。問題は、このハンドラーが「ユーザーが実際にキーを押したキーボードイベント」と「JavaScriptがdispatchEvent()で生成した偽のkeydownイベント」を区別しない点です。信頼できないJavaScriptがウェブビュー内で動作していれば、任意のキーストロークをメインVSCodeウィンドウに送り込むことができます。


5段階の攻撃チェーン—Jupyter Notebookから全プライベートリポジトリへ

Askarのブログの詳細解説をもとに、攻撃の5段階を整理します。

ステップ1:Jupyter NotebookのonerrorハンドラーでJavaScriptを起動

悪意あるリポジトリには.ipynb(Jupyter Notebook)ファイルが含まれており、マークダウンセルに以下のHTMLが埋め込まれています。

<img src="data:foobar" onerror="malicious_javascript()">

ウェブビューが存在し画像の読み込みが失敗すると、onerrorハンドラーが起動してウェブビュー内でJavaScriptが実行されます。

ステップ2:拡張機能インストール通知を待つ

悪意あるリポジトリの.vscode/extensions.jsonには攻撃者が用意した悪意ある拡張機能のIDが推奨拡張機能として記載されています。VSCodeはこのファイルを検出すると「拡張機能をインストールしますか?」という通知を表示します。JavaScriptは10秒間待機してこの通知の表示を待ちます。

ステップ3:Ctrl+Shift+Aで通知を承認

VSCodeのデフォルトキーバインドCtrl+Shift+Aは「Notifications: Accept Notification Primary Action」を実行します。JavaScriptが偽のkeydownイベントを送信するとこのコマンドが発動し、表示されている通知の主要アクション(インストール)が承認されます。

ステップ4:ローカルワークスペース拡張機能でパブリッシャー信頼ダイアログを回避

通常のマーケットプレイスからのインストールでは「Publisher Trust」ダイアログが表示されますが、Askarはこれをキーボードイベントでは突破できないと確認しています。代わりに悪意ある拡張機能を直接.vscode/extensions/ディレクトリに配置するローカルワークスペース拡張機能の機能を利用します。信頼済みワークスペース(github.devのワークスペースは常に信頼済み)内では、このディレクトリの拡張機能がパブリッシャー信頼チェックをスキップして読み込まれます。

ステップ5:カスタムキーバインドで悪意ある拡張機能を完全インストール

ローカル拡張機能のpackage.jsonにカスタムキーバインド(Ctrl+F1)を定義し、workbench.extensions.installExtensionコマンドをskipPublisherTrust: trueで呼び出す設定を追加します。JavaScriptがCtrl+F1の偽イベントを送信すると、攻撃者の拡張機能が完全にインストールされ、GitHubのOAuthトークンを取得してhttps://api.github.com/user/reposにクエリを送り、全プライベートリポジトリを列挙します。

VSCodeの既存防御が「最悪の事態」を防いだ

Askarはブログで、VSCodeのセキュリティチームが実装していた以下の防御が、今回の攻撃をより深刻な結果から防いだと述べています。

厳格なContent Security Policy(CSP)、DOMPurifyによるMarkdownのサニタイズ、拡張機能ビューでのscript-src 'none'ディレクティブです。

これらの防御がなければ、同一の手法を使ってデスクトップVSCodeユーザーに対するワンクリックRCE(任意コード実行)が実現していた可能性がありました。デスクトップVSCodeでElectronのNode.js APIが利用可能になれば、攻撃者はOSレベルのコマンドを実行できます。

なお、デスクトップ版VSCodeでもこの脆弱性は存在しますが、悪意あるリポジトリをクローンして開く操作が必要であり、github.devと比べて攻撃の容易さは低くなっています。

MSRCをめぐる構造的な不満——Nightmare Eclipseからの連続性とMicrosoftの無回答

今回の開示を「MSRCの脆弱性開示プロセスに失望した研究者たちが、ワーキングなエクスプロイトを公開することを選ぶという、最新の事例」とされています

Askarが選んだ理由

Askarはブログで、過去にVSCodeのバグをMSRCに報告した際にクレジットも修正の告知もなく静かに修正され、かつ「セキュリティ上の影響はない」と否定されるという対応を受けたと説明しています。そして「今後、VSCode関連のセキュリティバグについてはフルパブリックディスクロージャで公開することにした。他の研究者にも改善が見られるまで同じ方針を取ることを勧める」と宣言しました。

Nightmare Eclipse事案との連続性

この開示はNightmare Eclipse事案と深く関連しています。Nightmare Eclipseは数週間にわたって複数のWindowsゼロデイをMSRCへの協調なしに公開し、Microsoftは当初「未調整の公開は決して正当化できない」と声明を出し、「Digital Crimes Unitが犯罪行為者を可能にする者への対応を継続する」という、研究者への訴追を示唆するとも受け取られた言葉を使い、セキュリティコミュニティの激しい反発を招きました。

これを受けてMicrosoftは方針を転換し、当サイトの関連記事が詳報したように、「研究者への訴追意図はない」という新たな声明を発表しました。

その中でMicrosoftは次のように述べています。「セキュリティコミュニティはお客様の保護を助ける上で重要な役割を果たしています。私たちは誠実に関与し、これまでのやり取りにかかわらず、すべての研究者に対して敬意ある専門的な体験を提供することにコミットしています。一部の対応が適切でなかったことを認識しており、そこから学ぶよう取り組んでいます」。

しかしMicrosoftが方針転換した直後のAskarの公開と、コミュニティの反応は、この声明が実態の変化として受け止められていないことを示しています。

Microsoftは公式の質問に無回答

なお、「Askarへのクレジット付与の有無・なぜCVEが未アサインなのか・何人のgithub.devユーザーが修正前に影響を受けたのか」というThe Recordからの質問に対し、Microsoftは発行前に一切回答しませんでした。

この無回答という事実は、Askarをはじめとする研究者がMSRCへの不信感を持つ理由を、皮肉なほど明確に体現しています。

即時対処—github.devのCookieとサイトデータを削除する

Askarのブログが案内する唯一の現時点での緩和策は、ブラウザでgithub.devのサイトデータをクリアすることです。

github.devを一度も使ったことがないユーザーは、そもそもOAuthトークンがgithub.devのセッションに存在しないため、今回の攻撃は成立しません。過去にgithub.devを使用したことがあるユーザーは、以下の手順を実施してください。

Chromeでは、URLバーの設定アイコン(🔒または🛈)をクリックし、「Cookies and site data」→「Manage on-device site data」からgithub.devに関するデータを削除してください。これにより次回github.devにアクセスした際に「GitHub Repositoriesがサインインを求めています」というダイアログが表示されるようになり、攻撃者がこの脆弱性を悪用しようとした際に気づくことができます。

組織レベルの対応としては、開発者がgithub.devを使用する前に悪意あるリポジトリのリンクを踏まないよう注意喚起し、不審なリポジトリのgithub.devリンクをクリックしないというポリシーを周知してください。


FAQ

Q. この脆弱性は普通のgithub.comの操作では影響しますか? A. いいえ。影響を受けるのはgithub.devを使用している場合のみです。github.comからgithub.devへの遷移(URLの書き換えまたはメニューから起動)が発生した時に初めてOAuthトークンが生成・送信されます。通常のgithub.comのブラウジング・プルリクエスト・コード閲覧は影響を受けません。

Q. デスクトップ版のVSCodeも影響を受けますか? A. 同じ脆弱性が存在しますが、悪用には被害者が悪意あるリポジトリをクローンしてJupyterノートブックを開く操作が必要です。github.devと比べて攻撃の難易度は高くなります。また、デスクトップ版のVSCodeにはElectronのNode.jsアクセスが可能なため、VSCodeの既存防御(CSP等)が機能しなかった場合にはgithub.devより深刻なRCEに発展する可能性があります。

Q. Microsoft/GitHubはいつパッチを公開しますか? A. 記事執筆時点でMicrosoftからパッチのリリース時期についての公式情報はなく、CVEも未アサインです。The Recordの質問にも発行前に無回答でした。開発者はパッチが提供されるまでの間、上記のCookie削除によるサイトデータのクリアを実施することを推奨します。

Q. TeamPCPのVSCode拡張機能侵害と今回の脆弱性はどう関連しますか? A. 直接の技術的な関連はありませんが、どちらも「VSCodeのエコシステムを通じて開発者のOAuthトークン・ソースコード・認証情報を窃取する」という同一の攻撃カテゴリに属します。TeamPCPが拡張機能のサプライチェーンを汚染する手口を用いたのに対し、今回は悪意あるリポジトリのURLをクリックするだけという、より低いハードルで同様の結果(トークン窃取・リポジトリアクセス)を実現できる点で、攻撃面のリスクが広がっています。

Q. 自分のGitHubトークンが窃取されたかどうかを確認する方法はありますか? A. GitHubの「Settings → Security → Sessions」でアクティブセッションを確認し、見慣れない場所・デバイスからのセッションがないかを確認してください。また「Settings → Developer settings → Personal access tokens」とgithub.devのOAuthアプリ認証状態も確認してください。不審なアクセスが疑われる場合は、github.devの「GitHub Repositories」認証を取り消して再認証することを推奨します。


参考情報