PHPCSUtils: `eval()`関数を介したリモートコード実行の脆弱性 (AbstractArrayDeclarationSniff::getActualArrayKey()内)
### 影響
PHPCSUtilsのバージョン1.0.0-alpha1から1.2.2には、`PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff::getActualArrayKey()`メソッドに、任意のコードを実行される脆弱性が存在します。この脆弱なメソッドは、`AbstractArrayDeclarationSniff`を拡張し、`getActualArrayKey()`を呼び出すすべてのスニッフィングによって到達されます。
例えば、CIパイプラインでプルリクエストをチェックしたり、開発者がサードパーティのコードをレビューしたりする際に、信頼できないPHPコードに対してPHPCSを実行すると、スキャンを実行しているホスト上で任意のコマンドが実行される可能性があります。
この脆弱性は、メソッドが`eval()`関数を使用して配列キーの値を決定する際に発生します。悪意のある意図で作成された配列キー(例:`'system'('id')`)が、コードのスキャン時に実行されます。
### 既知の攻撃経路
脆弱なメソッドに到達する既知のコードパスには、以下のPHPCSExtraのスニッフィングが含まれます。
- `Universal.Arrays.DuplicateArrayKey`
- `Universal.Arrays.MixedArrayKeyTypes`
`AbstractArrayDeclarationSniff::getActualArrayKey()`を呼び出す他のパッケージも、同様の脆弱性を持つ可能性があります。
### 修正
この問題は、PHPCSUtils 1.2.3で修正されました。すべてのユーザーは、1.2.3以降のバージョンにアップグレードすることをお勧めします。
### 対策
すぐにアップグレードできないユーザーは、脆弱なメソッドに到達するスニッフィングを無効にすることができます。カスタムのルールセットに`<exclude>`タグを追加します(プレースホルダーの標準名とスニッフィング名を、ご自身の環境で使用されているものに置き換えてください)。
```xml
<rule ref="Standard">
<exclude name="Standard.Category.SniffName"/>
</rule>
```
例えば、「既知の攻撃経路」にリストされている2つのPHPCSExtraのスニッフィングを無効にするには、次のようにします。
```xml
<rule ref="Universal">
<exclude name="Universal.Arrays.DuplicateArrayKey"/>
<exclude name="Universal.Arrays.MixedArrayKeyTypes"/>
</rule>
```
スニッフィング機能が無効になっていることを確認するには、`-e`オプション付きでPHPCSを実行します。このオプションは、標準で実行されるすべてのスニッフィングを一覧表示します。除外されたスニッフィングは、出力に表示されなくなるはずです。
```
phpcs -e --standard=/path/to/ruleset.xml
```
### 謝辞
この脆弱性を適切に報告していただいた[@rodrigoprimo](https://github.com/rodrigoprimo)に深く感謝いたします。
### セキュリティ上の問題を報告するにはどうすればよいですか?
セキュリティ上の問題は、[PHPCSUtilsリポジトリの「セキュリティと品質」タブ](https://github.com/PHPCSStandards/PHPCSUtils/security)を通じて、非公開でご報告ください。
影響を受けるパッケージ:
- Composer (PHP) phpcsstandards/phpcsutils: 影響を受けるバージョン >= 1.0.0-alpha1, < 1.2.3、修正済みバージョン 1.2.3