Nx: Gitのリビジョンやリモート参照を介したOSコマンドインジェクションの脆弱性
## 概要
Nxのコア機能は、信頼できない値が埋め込まれたシェルコマンド文字列として、複数の`git`コマンドを実行します。これにより、Gitのリビジョンや参照であるべき値が、`/bin/sh`によって解析されてしまう可能性があります。攻撃者が利用できるエントリポイントは2つあります。1つは`affected`コマンドで、`nx.json`ファイル(および`NX_BASE` / `NX_HEAD`環境変数)の`defaultBase`または`affected.defaultBase`が`git merge-base`および`git diff`に渡されます。もう1つは`nx import`で、リモートリポジトリが広告するブランチ名が`git fetch`、`git checkout`、および`git config`に渡されます。いずれの場合も、リポジトリを制御している攻撃者、またはリポジトリに対してプルリクエストを送信する攻撃者は、Nxの通常のコマンドを実行するすべてのユーザーの機械で、任意のコマンドを実行できます。これには、CI(継続的インテグレーション)の実行環境も含まれます。
`affected`のパスは、この2つの脆弱性の中でより深刻なものです。`nx affected`や`nx show projects --affected`は、CI環境で頻繁に実行されるため、`nx.json`ファイルのみを変更したプルリクエストでも、そのジョブが持つ認証情報を使用して、実行環境でコードを実行できてしまいます。
## 深刻度
リポジトリの内容を制御できるユーザー(フォークのプルリクエストや、被害者がクローンするリポジトリなど)が、被害者が通常の`nx affected`または`nx import`コマンドを実行した場合に、この脆弱性を悪用できます。被害者の機械へのアクセスは必要ありません。現状では、この脆弱性が実際に悪用されているという証拠はありません。
## 対象バージョンと修正済みバージョン
| パッケージ | 脆弱性あり | 修正済み |
| --- | --- | --- |
| `nx` | `>= 14.0.0, < 22.7.8`; `>= 23.0.0, < 23.1.1` | `22.7.8`, `23.1.1` |
修正済みのバージョンより前のすべてのバージョンは、脆弱性があるものとして扱われます。
## 対策
**22.7.8**(22.xバージョン)または**23.1.1**(23.xバージョン)以降にアップグレードしてください。
```
nx migrate 23.1.1
```
修正は簡単なもので、設定変更は不要です。もしアップグレードできない場合は、信頼できないソースからの `nx.json` ファイルを、実行可能なコンテンツとして扱い、レビューしていないプルリクエストに対して `affected` コマンドを実行したり、信頼できないリポジトリに対して `nx import` コマンドを実行したりしないでください。
## 詳細
### `affected` コマンド
Nx は、`git merge-base` および `git diff` コマンドを文字列として構築し、それをシェルで実行することで、マージベースと変更されたファイルセットを計算します。これらの文字列に含まれるベースとヘッドのバージョンは、`nx.json` の `defaultBase` / `affected.defaultBase`、または `NX_BASE` / `NX_HEAD` 環境変数から取得され、関連するコードパスでは、`git show <revision>:<path>` を使用してファイルの内容を同じように読み込みます。シェルが文字列全体を解析するため、シェル構文を含むバージョン値は、`git` に渡されるのではなく、実行されてしまいます。
バージョンはダブルクォーテーションで囲まれていますが、これは保護にはなりません。POSIX シェルは、ダブルクォーテーション内でもコマンド置換を実行するため、`$(…)` のような値は、クォーテーションを抜け出すことなく実行されます。
### `nx import`
`GitRepository` ヘルパーは、すべての Git 操作(`fetch`、`checkout`、`reset`、`config` など)を、引数をシェルコマンド文字列に埋め込むことによって実行します。信頼できない引数は、ブランチ名です。`nx import` は、リモートが提供するブランチを一覧表示し、ユーザーに選択させ、選択された名前をこれらのコマンドに渡します。悪意のあるリポジトリは、自身のブランチ名を制御できるため、選択されたブランチ名に基づいて実行されるコマンドも制御できます。
## 貢献者
- **Arkadiusz Marta** (RE:SOURCE) — 報告者
影響を受けるパッケージ:
- npm (JavaScript) nx: affected >= 14.0.0, < 22.7.8、22.7.8 で修正済み
- npm (JavaScript) nx: affected >= 23.0.0, < 23.1.1、23.1.1 で修正済み