Release of Yii 2.0.15 and Vulnerability Database Extensions

    Today we are releasing Yii updates for several recent versions 2.0.x and official non-relational database support extensions to fix vulnerabilities found. Patches fix the problem in the methods of the ActiveRecord layer: findOne()and findAll(), which can allow SQL injection if the incoming data is not prepared properly.


    We see this as a vulnerability in Yii because the documentation for these methods did not explicitly warn that in some cases, transmitting unfiltered user data could be dangerous. We thank Analitic1983 ( Habr , GitHub ) for discovering this vulnerability.


    The problem relates not to the framework itself, but to the documentation on the use of these methods in the application. We updated the documentation and additionally provided examples of code that could be dangerous. However, updating the documentation will not fix applications in which developers are already using methods findOne()and are findAll()unsafe. To avoid the worst case scenario of SQL injection, we also changed the behavior of these methods and added forced input filtering, which limits the list of possible column names to the list of properties of the ActiveRecord model.


    The fix, although it removes the vast majority of problems, does not fix all of them, because later in the article we will examine in detail which code is vulnerable and what needs to be done to protect itself.


    List of vulnerable classes, methods and packages


    • Methods yii\db\ActiveRecord::findOne()and yii\db\ActiveRecord::findAll()in the package yiisoft/yii2, to which the vulnerability number CVE-2018-7269 is assigned. Methods allow SQL injection if incoming data is not sufficiently filtered. An attacker can execute an arbitrary SQL query or bypass the filtering conditions established at the level of the query being executed.
    • Methods yii\redis\ActiveRecord::findOne()and yii\redis\ActiveRecord::findAll()in the package yiisoft/yii2-redis, for which we assign the vulnerability number CVE-2018-8073. Methods allow remote code execution on the Redis server in the form of LUA scripts. An attacker can execute arbitrary LUA code and modify data on the server side.
    • Methods yii\elasticsearch\ActiveRecord::findOne()and yii\elasticsearch\ActiveRecord::findAll()in the package yiisoft/yii2-elasticsearch, for which we assign the vulnerability number CVE-2018-8074. Methods allow the implementation of search terms that are not provided by the developer.

    Is my application vulnerable?


    The vulnerability applies to all releases of Yii2 and is fixed in version 2.0.15. For versions prior to 2.0.15, we will release two patch updates: 2.0.13.2 and 2.0.12.1, which apply the patch to 2.0.13.1 and 2.0.12, respectively. Users of version 2.0.14 can upgrade to version 2.0.15, as there are no other changes in the release.


    Invulnerable code


    Methods findOne()and findAll()take one argument, which can be a scalar or an array. If the code that calls this method ensures that the passed value is scalar, or that the structure of the passed array cannot be modified externally, your application is invulnerable. The following code examples are NOT affected by this vulnerability. Call examples are findOne()also valid for the method findAll().


    // yii\web\Controller гарантирует, что $id – это скаляр
    public function actionView($id)
    {
        $model = Post::findOne($id);
        // ...
    }

        // приведение к числу (int) или строке (string) гарантирует, что массив не может быть передан в метод (будет выброшено исключение о невозможности преобразования массива в скаляр)
        $model = Post::findOne((int) Yii::$app->request->get('id'));

    // Явное указание имени столбца и передача скаляра или массива как значения не подвержены уязвимости
    $model = Post::findOne(['id' => Yii::$app->request->get('id')]);

    Vulnerable code


    However, the following code is VULNERABLE, and the attacker can create a query that allows you to search for an arbitrary column, or even SQL injection:


    $model = Post::findOne(Yii::$app->request->get('id'));

    This update fixes the possibility of injecting SQL injection, but the attacker can still search for columns other than the primary key, which can violate the business logic of the application.


    How to get an update?


    We are releasing a security update for the last three Yii2 releases: 2.0.14, 2.0.13, and 2.0.12. If you are using an older version of the framework, you need to upgrade Yii to at least the nearest version in which the problem is fixed.


    If you are using Yii 2.0.14:


    composer require "yiisoft/yii2":"~2.0.15.0"

    If you are using Yii 2.0.13:


    composer require "yiisoft/yii2":"~2.0.13.2"

    If you are using Yii 2.0.12:


    composer require "yiisoft/yii2":"~2.0.12.1"

    If you use the extension yii2-redis:


    composer require "yiisoft/yii2-redis":"~2.0.8"

    If you use the extension yii2-elasticsearch:


    composer require "yiisoft/yii2-elasticsearch":"~2.0.5"

    In addition to updating Yii, we also recommend checking in your application code that uses methods findOne()and findAll()for the possibility of searching in an arbitrary column. We also remind you that the where()and methods filterWhere()never escape column names, so if you need to use a variable received from the user as a column name, make sure that you do it safely.


    UPD: the update broke the work ActiveRecord::refresh()( github ), because patches were additionally released: 2.0.15.1 , 2.0.13.3 , 2.0.12.2


    Also popular now: