本日、発見された脆弱性を修正するために、いくつかの最新バージョン2.0.xおよび公式の非リレーショナルデータベースサポート拡張機能のYiiアップデートをリリースしています。 パッチは、ActiveRecordレイヤーのメソッドであるfindOne()
およびfindAll()
の問題を修正します。これにより、着信データが適切に準備されていない場合にSQLインジェクションを許可できます 。
これらのメソッドのドキュメントでは、フィルタリングされていないユーザーデータの送信が危険な場合があることを明示的に警告していないため、これをYiiの脆弱性と見なしています。 この脆弱性を発見してくださったAnalitic1983 ( Habr 、 GitHub )に感謝します。
この問題は、フレームワーク自体ではなく、アプリケーションでのこれらのメソッドの使用に関するドキュメントに関連しています。 ドキュメントを更新し、さらに危険なコードの例を提供しました。 ただし、ドキュメントを更新しても、開発者がすでにfindOne()
およびfindAll()
メソッドを使用しているアプリケーションは安全ではありません。 最悪のシナリオであるSQLインジェクションを回避するために、これらのメソッドの動作を変更し、強制入力フィルタリングを追加しました。これにより、可能な列名のリストがActiveRecordモデルのプロパティのリストに制限されます。
この修正は、大部分の問題を除去しますが、すべての問題を解決するわけではありません。なぜなら、この記事の後半で、どのコードが脆弱で、それ自体を保護するために何が必要かを詳しく調べるからです。
脆弱なクラス、メソッド、およびパッケージのリスト
yiisoft/yii2
パッケージのyii\db\ActiveRecord::findOne()
およびyii\db\ActiveRecord::findAll()
yiisoft/yii2
には、脆弱性番号CVE-2018-7269が割り当てられています。 メソッドは、着信データが十分にフィルタリングされていない場合にSQLインジェクションを許可します 。 攻撃者は、任意のSQLクエリを実行したり、実行中のクエリのレベルで確立されたフィルタリング条件をバイパスしたりできます。yiisoft/yii2-redis
パッケージのyii\redis\ActiveRecord::findOne()
およびyii\redis\ActiveRecord::findAll()
yiisoft/yii2-redis
にはyiisoft/yii2-redis
脆弱性番号CVE-2018-8073がyiisoft/yii2-redis
ます。 メソッドを使用すると、LUAスクリプトの形式でRedisサーバーでリモートコードを実行できます。 攻撃者は任意のLUAコードを実行し、サーバー側でデータを変更できます。yiisoft/yii2-elasticsearch
パッケージのyii\elasticsearch\ActiveRecord::findAll()
yii\elasticsearch\ActiveRecord::findOne()
およびyii\elasticsearch\ActiveRecord::findAll()
yii\elasticsearch\ActiveRecord::findOne()
yii\elasticsearch\ActiveRecord::findAll()
yiisoft/yii2-elasticsearch
にはyiisoft/yii2-elasticsearch
脆弱性番号CVE-2018-8074がyiisoft/yii2-elasticsearch
ます。 メソッドを使用すると、開発者が提供していない検索語を実装できます。
私のアプリケーションは脆弱ですか?
この脆弱性はYii2のすべてのリリースに適用され、バージョン2.0.15で修正されています。 2.0.15より前のバージョンでは、2.0.13.2と2.0.12.1の2つのパッチアップデートをリリースします。これらはそれぞれ2.0.13.1と2.0.12にパッチを適用します。 バージョン2.0.14のユーザーは、リリースに他の変更がないため、バージョン2.0.15にアップグレードできます。
傷つきにくいコード
findOne()
およびfindAll()
メソッドは引数を1つ取ります。引数はスカラーまたは配列です。 このメソッドを呼び出すコードが、渡された値がスカラーであること、または渡された配列の構造を外部から変更できないことを保証している場合、アプリケーションは脆弱ではありません。 次のコード例は、この脆弱性の影響を受けません。 findOne()
の呼び出しfindOne()
、 findAll()
メソッドでも有効です。
脆弱なコード
ただし、次のコードは脆弱であり、攻撃者は任意の列、またはSQLインジェクションを検索できるクエリを作成できます。
$model = Post::findOne(Yii::$app->request->get('id'));
この更新により、SQLインジェクションを注入する可能性が修正されますが、攻撃者は依然としてプライマリキー以外の列で検索でき、アプリケーションのビジネスロジックに違反する可能性があります。
アップデートの入手方法は?
Yii2の最新の3つのリリース(2.0.14、2.0.13、および2.0.12)のセキュリティ更新プログラムをリリースしています。 フレームワークの古いバージョンを使用している場合、少なくとも問題が修正された最も近いバージョンにYiiをアップグレードする必要があります。
Yii 2.0.14を使用している場合:
composer require "yiisoft/yii2":"~2.0.15.0"
Yii 2.0.13を使用している場合:
composer require "yiisoft/yii2":"~2.0.13.2"
Yii 2.0.12を使用している場合:
composer require "yiisoft/yii2":"~2.0.12.1"
yii2-redis
を使用している場合:
composer require "yiisoft/yii2-redis":"~2.0.8"
yii2-elasticsearch
拡張機能を使用している場合:
composer require "yiisoft/yii2-elasticsearch":"~2.0.5"
Yiiの更新に加えて、 findOne()
およびfindAll()
メソッドを使用するアプリケーションコードをチェックインして、任意の列で検索できるようにすることもお勧めします。 また、 where()
およびfilterWhere()
メソッドは列名をエスケープしないため、ユーザーから受け取った変数を列名として使用する必要がある場合は、これを安全に行うようにしてください。
UPD:更新によりActiveRecord::refresh()
( github )の動作が中断されたため、パッチパッチが追加リリースされました: 2.0.15.1、2.0.13.3、2.0.12.2