Closed9

VS Code の Workspace Trust(ワークスペースの信頼)について

Yuki HattoriYuki Hattori

コンセプト

https://github.com/microsoft/vscode/issues/106488

The trusted workspaces concept is intended to centralize and unify a security conscious decision required by a variety of VS Code features. The easiest existing example to understand of this decision is with the ESLint extension. The ESLint extension will try to use the eslint module in the current folder that is opened in VS Code and execute code from it. Since you may have checked out a random repository from the web, this could be dangerous if the repository contains a corrupt eslint module. Notice that ESLint is not trying to be malicious, but rather, the repository/corrupt module is taking advantage of this automatic code execution.

With Trusted Workspaces, the user will be able to declare whether or not they trust the folder that is opened in VS Code before these features are executed.

背景

説明に ESLint の例が出ているが、実際、 ESLint の拡張機能 は 1 年前から独自のパーミッション管理を備えていて、ワークスペース単位で許可しないと動かない設計になっていた。

これは CVE-2020-1416 脆弱性への対策として実装されている。それまではワークスペースの JS を開いたタイミングでプロジェクト内の ESLint が走っていて、改ざんされた ESLint だろうが、悪意のある設定を含むプロジェクトだろうが、暗黙的にコードが実行されていた。

https://github.com/microsoft/vscode-eslint/issues/1012

ユーザーからすると、ダイアログでいちいち許可を聞かれるのは UX の低下であり、上記 Issue に批判意見も多くあったが、セキュリティとのトレードオフなので致し方ないという論調で進む。

最終的にはモーダルダイアログを使わないように UX が改善されたが、Workspace Trust リリースのタイミングで完全にそれを使うよう切り替わっている。

他の Node.js ツールを対象とする拡張や、それ以外の言語でも、ユーザーのコードに基づいて実行するタイプの拡張機能には、同じ脆弱性が潜在的に存在する可能性があり、 暗黙的なコード実行を攻撃ベクトルとして狙われる恐れがある。ただし、その問題を実際に把握して対策を履行している拡張機能は、ほんのひと握りという状態だった。

例えば Prettier も、この脆弱性に対応すべく、 ESLint と同じダイアログの実装を行っていたが、2021 年 3 月 (v6) と、先の脆弱性の顕在化から約 1 年ほど経過した段階でようやく実装されたものだった。

事実、拡張機能毎にパーミッション管理をしてしまうと、UX の統一性がなく、ユーザーに負担がかかる。また、拡張開発者にとっても、脆弱性対応のために自前でパーミッション管理を実装しなければならなかったため、負担がかかっていた。Workspace Trust は、そういった問題を包括して解決する機能と言える(Prettier 拡張機能は、6月後半にリリースされた v8 で独自のパーミッション管理を全廃し、Workspace Trust に切り替えている)。

Yuki HattoriYuki Hattori

Workspace Trust で何から保護されるのか?

Many features of VS Code allow third-party tools and extensions to run automatically, such as linting or format on save, or when you do certain operations like compiling code or debugging. An unethical person could craft an innocent looking project that would run malicious code without your knowledge and harm your local machine. Workspace Trust provides an extra layer of security by trying to prevent code execution while you are evaluating the safety and integrity of unfamiliar source code.

-- https://code.visualstudio.com/docs/editor/workspace-trust#_what-does-workspace-trust-protect-against

VS Code の拡張機能は基本的に何でもできてしまうので、clone してきたプロジェクトの安全性が確認できるまで、悪意のある任意コードの暗黙的実行を防ぐためのセキュリティレイヤーとして機能する。

Yuki HattoriYuki Hattori

拡張機能側で必要な対応

https://github.com/microsoft/vscode/issues/120251

拡張機能が Workspace Trust に対応しているかを package.jsoncapabilities.untrustedWorkspaces で明示する必要がある。

  • true: 制限モードでも動く
  • false: 制限モードでは動かない
  • 'limited': 制限モードでは一部の機能が制限された状態で動く(詳細な設定も可能)

何もしない場合、untrustedWorkspaces: false として扱われ、制限モードでは拡張機能が OFF になる。これは安全だが、拡張機能の利便性が落ちてしまう。

制限の選択

基本的に自己申告制なので、制限モード下で実行できるようにすること自体は簡単だが、 正しく意図を理解しないと、先に述べたような脆弱性を孕む。 そのため、拡張機能の開発者は、挙動に基づいて適切に設定を選択する必要がある。

特に、ユーザーのプロジェクトから任意のコードを実行できるようなものは制限を検討すべき。

制限モードでの動作を許可しても良い例

  • 拡張機能の package.jsonmain を含んでいない場合
    • VS Code テーマを提供する拡張機能
    • シンタックスハイライト (TextMate JSON) を提供する拡張機能
  • 拡張機能の動作がワークスペース内のコンテンツに依存しない場合vscode-pets などのように、拡張機能側で全ての動作が完結しているもの)

制限を検討すべき例

  • ワークスペース内のコードが実行される場合
    • ワークスペースで開かれたプロジェクトの依存関係にあるツールと連携する拡張機能などは、サプライチェーン攻撃などによって正規ではないものが使われる可能性があるため、制限が必要
    • JS の場合、ツール自体は拡張機能側で管理していたとしても xxx.config.js のような設定ファイルを読み込む時に任意コード実行が可能なケースがあるので注意
  • ワークスペース設定で挙動を変更できる場合
    • ワークスペース固有の設定を .vscode/settings.json で設定できるため、その設定がワークスペース固有の攻撃ベクトルになる可能性がある
    • 'limited' を選択した場合、 restrictedConfigurations で拡張機能の設定項目ごとにワークスペース側からの設定を無効化できる
Yuki HattoriYuki Hattori

Workspace Trust で守られる例 (PoC)

https://github.com/lucky/bad_actor_poc

rust-analyser 拡張機能を経由することで、 プロジェクトを開くだけで .ssh/id_rsa が盗まれてしまう 。拡張機能の「暗黙的なコード実行」を実際に狙った例。

https://www.youtube.com/watch?v=RRLw3OBJ0fM

現状、rust-analyser は Workspace Trust の制限モードでは無効化されるので、ダイアログに従って制限モードで開けば被害を受けない。

Workspace Trust のリリース直前に、この PoC が Hacker News などで話題になった が、前述の通り、オリジナルの脆弱性は 2020 年に報告されたものなので、別にこの PoC が Workspace Trust の契機となったわけではない。

Yuki HattoriYuki Hattori

ダイアログがうるさいので無効にしたい

できるけど、上記のような悪意のあるリポジトリ例から守られなくなってしまうので、決しておすすめされない。

うるさいからという理由で OFF にするには、脆弱性の高リスク (CVE-2020-1416 では CVSS v3: 8.8 / v2: 9.1) との釣り合いが取れていない。被害にあっても構わないという人だけ、自己責任でどうぞ。

Yuki HattoriYuki Hattori

Workspace Trust の許可はどこで設定/管理できる?

左下の設定アイコン ⚙️ の "Manage Workspace Trust" (日本語の場合は『ワークスペースの信頼を管理』) からアクセスできる。

Yuki HattoriYuki Hattori

公式ブログでの解説(7/7追記)

https://code.visualstudio.com/blogs/2021/07/06/workspace-trust

  • 機能が実装された経緯
  • なぜ単なるエディタにこんな機能が必要なのか?
  • 拡張機能それぞれで対応した時のプロンプト地獄について(「もぐらたたき」と形容)
  • ダイアログを採用した理由
  • Workspace Trust の使用例
  • etc...

内容はほぼこの記事でも網羅できているはず…。
先述の bad_actor_poc の他、Unicode を使ったコード上で悪用可能性のある問題 にも一部言及されている。

Yuki HattoriYuki Hattori

ダイアログを採用した理由

VS Code は最初、通知のインターフェースをベースとした、作業をブロックさせないプロンプトを検討したとのこと。

しかし、実際のユーザーの使用状況を見ると、通知は単に無視されることが多く、実際にこの通知から承認された例はごくわずかだったらしい。

その結果、この通知の意味を理解せずに閉じてしまったユーザーにとっては、拡張機能が制限モード下で動かなくなり、いわゆる「なにもしてないのにこわれました」状態になってしまう。

その結果、拡張機能を再度有効にするためのトラブルシューティング、および Workspace Trust の概念の理解に余計に時間がかかる悪循環になってしまうという問題が発生。最終的にこのデザインは却下され、現在のダイアログ形式でユーザーに明示的にアクションを求める形になった。

このスクラップは2021/11/23にクローズされました