誤設定された VSCode 拡張機能から脱却する(2023)

2026/02/21 5:39

誤設定された VSCode 拡張機能から脱却する(2023)

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

この記事は、Visual Studio Code(VS Code)で発見・公開・悪用された4つの重大脆弱性を記録した2部構成のブログシリーズです。これらの脆弱性は3つが拡張機能(SARIFビューワー、Live Preview)に影響し、1つがエディタ自体(CVE‑2022‑41042)に影響します。Microsoft はこれらの発見に対して7,500ドルの報奨金を授与しました。

4つすべての欠陥は、攻撃者が Webview サンドボックスから脱出し、ローカルファイルを外部送信したり、ユーザーのマシン全体を完全に乗っ取ったりすることを可能にします。

  • SARIFビューワー:不安全な
    ReactMarkdown
    のレンダリング(
    escapeHtml = false
    )と許容的な
    localResourceRoots
    が組み合わさり、攻撃者が
    ~/.ssh/id_rsa
    など任意のファイルを読み取れるようになります。
  • Live Preview: (1)
    innerHTML
    を介した HTML/JavaScript の注入で、postMessage ハンドラから srcdoc‑iframe をホストできる。CSP は nonce ベースの
    script-src
    を使用しますが、nonce をブルートフォースまたは回復することは効果的ではありません。(2) そのローカル HTTP サーバーにパス・トラバーサル脆弱性があり、ワークスペース内外から任意のファイルを読み取れます。
  • DNS リバインディング:バックグラウンドで実行される Live Preview サーバーを利用し、CORS 制限を回避する方法としてデモンストレーションされています。
  • DNS プレフェッチトリック:攻撃者は
    <link rel="dns-prefetch">
    タグを使用してサブドメインにファイル内容を埋め込みます。

記事では、Webviews の作成、

localResourceRoots
の設定、nonce の生成、および URL の解析の具体的なコードスニペットが提供されています。

Microsoft は 2022 年 8 月から 10 月の間に各脆弱性を別々のコミット(c054421/98816d9 – SARIF; 4e029aa – Live Preview; 9d26055/88503c4 – コアバグ)で修正しました。

推奨される緩和策: CSP を強化(nonce/hash の使用、unsafe‑inline の回避)、

localResourceRoots
を拡張機能フォルダに限定、任意の
innerHTML
をサニタイズ、postMessage ハンドラを検証、厳格な URL 解析を実施、ローカルサーバーのポート番号をランダム化、およびホストヘッダー許可リストを設定します。

次の記事では、拡張機能が正しく構成されている場合でも Webview サンドボックスを回避する VS Code コアバグについて検証します。

本文

TL;DR
この2部構成のブログシリーズでは、VSCode 拡張機能(SARIF Viewer と Live Preview)における3つの脆弱性と、VSCode 本体に対する1つの脆弱性(CVE‑2022‑41042、賞金 7,500 USD)をどのように発見し報告したかを解説します。記事ではそれぞれの欠陥の根本原因を特定し、攻撃者がマシンを乗っ取るために実際に利用できるエクスプロイト例を提示するとともに、同様の問題を防ぐ方法を推奨しています。


VSCode 拡張機能のセキュリティが重要な理由

VSCode の拡張機能はフルファイルシステムとシェルへのアクセス権を持ちます。攻撃者が拡張内で JavaScript を実行できれば(例:XSS 経由)、ホストシステムを完全に乗っ取ることが可能です。

Microsoft の SARIF Viewer と Live Preview を監査した際、悪意のあるウェブサイトを閲覧中に拡張機能が動作しているときに、ローカルファイル(SSH キーも含む)をすべて盗み取ることができる高い深刻度のバグを発見しました。


VSCode Webview – ざっくり復習

  • サンドボックス化された UI パネル
    <iframe>
    と同様)。
  • Webview 内では Node.js API が無効化され、ファイル読み込みやコマンド実行はメイン拡張のみが行える。
  • セキュリティオプション:
    • enableScripts
      – スクリプトを許可するか(デフォルトは
      true
      )。
    • localResourceRoots
      – ファイルアクセス先を制限(デフォルトはワークスペース+拡張フォルダ)。
    • Content‑Security‑Policy (CSP) – 画像、CSS、スクリプト等のソースを限定。

Webview は

postMessage()
を介してメイン拡張と通信します。


脆弱性 1 – SARIF Viewer における HTML/JavaScript 注入

何が壊れていたか

ビューアは ReactMarkdown の

escapeHtml={false}
を使用して SARIF 結果の説明を描画しています。これにより、悪意ある SARIF ファイルを開くと任意の HTML と JavaScript が注入できるようになっていました。

証明実験

不正なソースを持つ

<img>
onerror
ハンドラを設定すると、Webview 内で JavaScript を実行できます。

エスカレーション – ローカルファイルの漏洩

  • Webview の
    localResourceRoots
    が誤って全パス(例:
    z:\
    )へのアクセスを許可していた。
  • Webview から
    https://file+.vscode-resource.vscode-cdn.net/<path>
    に fetch を送ると、ファイル内容が取得できました。
  • CSP はアウトバウンドリクエストを禁止していましたが、DNS‑prefetch
    <link>
    タグでサブドメインにペイロードを埋め込むことで回避しました。

HTML 注入・パストラバーサル・DNS エクスフィルトレーションの組み合わせにより

~/.ssh/id_rsa
などのファイルを盗み取ることが可能でした。

修正と検知

  • localResourceRoots
    を拡張フォルダまたはワークスペースのみへ限定。
  • Markdown のレンダリング時に
    escapeHtml={true}
    を使用。
  • CSP ノンスは暗号学的に安全な RNG(例:
    crypto.randomBytes
    )で生成。

Semgrep の更新された ReactMarkdown ルール(PR #2307)は同様の問題を自動検知できます。


脆弱性 2 – Live Preview における HTML/JavaScript 注入

何が壊れていたか

Live Preview はポート 3000 上でローカル HTTP サーバーを起動し、

<iframe>
を埋め込んでいます。拡張の
link-hover-start
メッセージハンドラはユーザー入力を直接 Webview の innerHTML にコピーし、サニタイズが行われていませんでした。

JavaScript の実行

  • <script>
    タグを直接挿入しても Webview 内では実行されません。
  • 代わりに srcdoc iframe を注入すると、ブラウザは同一オリジンとして扱うため、そのスクリプトが Webview コンテキストで実行できます。

CSP の課題 – ノンス

Webview の CSP は

Math.random()
で生成された 64 桁のノンスを使用。ブルートフォースは非現実的で、
Math.random()
の状態復元も失敗します(iframe、外部 Webview、メイン拡張それぞれが独自 RNG を持つため)。

結果

srcdoc iframe で HTML 注入とスクリプト実行は可能でしたが、CSP により完全なエクスプロイトは阻止されました。次の脆弱性では別のベクトルを突きます。


脆弱性 3 – Live Preview のローカル HTTP サーバーにおけるパストラバーサル

何が壊れていたか

サーバーは

http://127.0.0.1:3000/?../../../../../../etc/passwd?
のような URL を受け取り、手書きのクエリ解析により
/etc/passwd
を解決します。通常ブラウザは
../
を正規化しますが、サーバー側ではその処理を行っていません。

攻撃シナリオ

シナリオ仕組み
攻撃者がファイルを制御悪意ある HTML ファイルからローカルサーバー経由で任意のホスト上のファイルを取得し、漏洩させる。
DNS リバインディング攻撃者サイトをホストし、DNS を
192.168.x.x
127.0.0.1
の間で切り替える。Live Preview が動作中にサイトへアクセスすると、ドメインが localhost に解決された瞬間にトラバーサル攻撃が実行されローカルファイルが漏洩。

どちらもサーバーがパスを正規化せず、許可されたルート内にあるかどうかを確認しない点に依存しています。


VSCode Webview を安全に保つ方法

ガイドライン推奨
CSP
default-src 'none'
から始め、
unsafe-inline
は避ける。ノンスやハッシュは
crypto.randomBytes(16)
で生成。
localResourceRoots拡張のインストールフォルダに限定。任意のファイルシステムパスを公開しない。
postMessage ハンドラすべての入力を検証。SQL/コマンド注入、任意ファイル読み書きを防止。
ローカル HTTP サーバー
URL
クラスで URL を解析し、正規化後に解決パスが許可されたルート内にあるか確認。
DNS リバインディング対策ランダムポートで起動し、静的ポートへ
portMapping
する。Host ヘッダーを
localhost/127.0.0.1
に限定し、認証も検討。
innerHTML へのユーザー入力は避ける
.innerText
を使用するか、適切なサニタイズライブラリで処理。

これらの原則に従うことで、上記で示したような攻撃を受けにくい拡張機能が構築できます。


タイムライン(参考)

  • 2022 年8月12日 – Microsoft に脆弱性 1 を報告
  • 2022 年8月13–16日 – コミット
    c054421
    98816d9
    で修正
  • 2022 年9月7日 – 脆弱性 2・3 を報告
  • 2022 年9月14日 – 脆弱性 2(コミット
    4e029aa
    )を修正
  • 2022 年10月5日 – 脆弱性 3(コミット
    9d26055
    88503c4
    )を修正

次回の投稿では、拡張機能が正しく構成されている場合でも Webview のサンドボックスから脱出できる VSCode 本体のバグについて検証します。

同じ日のほかのニュース

一覧に戻る →

2026/02/21 2:58

「Androidをオープンに保つ」

## 日本語訳: F‑Droidは、GoogleのAndroidポリシーの変化についてコメントしながら、新しい **Basic 2.0‑alpha3** ビルドを公開しました。 - **FOSDEM26** でユーザーは、GoogleがAndroidをロックダウンする計画を中止したと聞き安心しましたが、8月の発表ではその計画がまだ有効であることが示されています。 - 記事は、Google の「advanced flow」主張の曖昧さと、Android 16 QPR2/3 や Android 17 Beta 1 の明確なリリース日が設定されていない点を批判しています。 - **バナー警告** は、Google がゲートキーパーになる前に時間がなくなることをユーザーに知らせ、IzzyOnDroid、Obtainium、および他のダウンローダーでも同様のバナーが表示されます。 - 新しい Basic リリースには、更新された翻訳、インストール済みアプリの CSV エクスポート、インストール履歴、ミラー選択器、スクリーンショット防止機能、ツールチップ、新しいオーバーフローメニュー、永続的な並べ替え順序、Material 3 スタイル、およびさまざまなバグ修正が含まれています。 Basic 1.23.x を使用しているユーザーは、このアルファを受け取るために「Allow beta updates」を手動で有効にする必要があります。 - **いくつかのアプリが更新されました**:Buses 1.10、Conversations/Quicksy 2.19.10+、Dolphin Emulator 2512、Image Toolbox 3.6.1(AIツール)、Luanti 5.15.1、Nextcloud ファミリー(Nextcloud 33.0.0、Cookbook 0.27.0、Dev 20260219、Notes 33.0.0、Talk 23.0.0)、ProtonVPN 5.15.70.0(WireGuard のみ)、Offi 14.0、QUIK SMS 4.3.4、および SimpleEmail 1.5.4。 - **5 つのアプリが削除されました**:Chord Shift、OpenAthena™ for Android、Tibetan Keyboard、Tibetan Pad、Tomdroid。 - **新しいアプリが追加されました**:NeoDB You(Material 3/You を採用した NeoDB のネイティブ Android アプリ)。 - 280 件を超えるアプリが更新され、注目すべきものとして Aurora Store 4.8.1、Bando.js Gadgetbridge 0.89.1‑banglejs、DuckDuckGo Privacy Browser 5.266.0、Element X 26.02.0、OpenTracks v4.26.0、Proton Pass 1.37.2 などがあります。 - F‑Droid は読者に RSS フィードの購読、TWIF フォーラムスレッドへの参加、および寄付ページでの寄付を促しています。 この改訂された概要はリストから主要なポイントをすべて保持し、不必要な推測を避け、明確なメインメッセージを提示し、曖昧または混乱する表現を除去しています。

2026/02/21 6:25

Dependabot をオフにします。

## Japanese Translation: ## 要約 DependabotはGoプロジェクトで細かいパッケージフィルタリングが不足しているため、頻繁に無関係なセキュリティアラートを生成します。著者はDependabotを停止し、最新の依存関係に対して`govulncheck`とテストスイートを実行するスケジュール済みGitHub Actionで置き換えることで、ノイズを劇的に減らしながらも実際の脆弱性は検出できることを示しています。 重要な例として、`filippo.io/edwards25519`(v1.1.1)の修正が挙げられます。このパッチはDependabotのデフォルト動作により、関連しないリポジトリ―例えばWycheproof―でも何千件ものPRを生成しました。対照的に、`govulncheck`は静的解析後に脆弱なシンボルが到達不能であると判断し、著者のプロジェクトでは「脆弱性なし」と報告します。 Go Vulnerability Database はモジュール、バージョン、シンボル、CVE参照などの詳細メタデータを提供しており、こうした精密なフィルタリングを可能にしています。著者は毎日実行されるワークフロー(`go get -u -t ./...`)と10:22 UTCに実行される`govulncheck`を組み合わせ、真の脅威に対してのみアラートが上がるようにしています。 CI環境を潜在的なサプライチェーン攻撃から保護するため、ワークフローではgVisorを使用したサンドボックス化ステップ`geomys/sandboxed-step`を採用しています。この手法は、各依存関係のスケジュールではなくプロジェクト自身のリリースサイクルに合わせて依存関係を更新することを推奨し、継続的なバンプなしで早期検出を実現します。 この戦略は、Go Security Team が2020–21年にデータベース品質と静的解析フィルタの改善に焦点を当てたものと一致しており、Geomys のリテーナー契約(Ava Labs、Teleport、Tailscale、Sentry)によって支援されています。著者は他の開発者にも同様のワークフローを採用するよう促し、Bluesky(@filippo.abyssdomain.expert)または Mastodon(@filippo@abyssdomain.expert)でフォローしてもらうことを読者に呼びかけています

2026/02/20 22:51

**Ggml.ai、Hugging Faceと提携しローカルAIの長期的進展を確保** - 軽量機械学習モデルのリーディングプロバイダーであるGgml.aiが、Hugging Faceとパートナーシップを結びました。 - 本協業は、世界中におけるローカルAIソリューションの継続的な開発・展開を確実にすることを目的としています。 - 両社は資源やベストプラクティス、コミュニティサポートを共有し、デバイス上で動作するインテリジェンスのイノベーションを加速させていきます。

## 日本語訳: > ggml.ai の創設者は、AI を真にオープンに保ちつつ、ggml/llama.cpp スタックのメンテナンスに専念するため、Hugging Face に参加します。このパートナーシップはプロジェクトの長期的な持続可能性を保証し、ユーザーと貢献者に新たな機会を提供します。これまでの 3 年間の協力により、コア機能・ユーザーインターフェース・マルチモーダルサポート・GGUF 対応が追加されました。Llama.cpp は多くのコンシューマー ハードウェア上で動作するプライベート AI プロジェクトに不可欠となっており、コミュニティは依然として独自に構成設計を行い、Hugging Face はリソースを提供しつつコードを 100 % オープンソースのまま保ちます。今後、チームはユーザー体験を優先し、ggml/llama.cpp を Hugging Face の Transformers ライブラリに「ワンクリック」で統合し、ローカル推論がクラウドソリューションと競合できるようパッケージングを改善します。これらの取り組みは、使いやすいエッジ推論スタックを構築し、開発者に日常デバイス上でプライベート AI を構築するための安定した基盤を提供するとともに、世界中でオープンソーススーパインテリジェンス エコシステムを拡大することを目的としています。