Today we are releasing several versions for Yii 2.0.x and official extensions to fix a security issue.
The problem addressed in these patches exists in ActiveRecord shortcut methods findOne()
and findAll()
, which may
allow SQL injection if input is not prepared properly. We consider this as a security issue in Yii because the documentation for these methods did not contain an explicit warning that there are cases when passing unfiltered user input might be dangerous. Thanks to analitic1983 for making us aware of the issue.
The nature of this issue does not solely exists in the Yii Framework but depends on how an application uses Yii.
We have changed Yii to be more robust against the worst impact of the problem (SQL injection), but applications may still be vulnerable
and changes to application code are necessary in some cases. As a safety measure, findOne()
and findAll()
are now limited to filter on
columns that are AR properties only. In the following we will explain the problem in more detail
and show which application code is affected and what needs to be adjusted on upgrade.
For discussion on this issue, there is a forum topic.
Summary of Affected Classes, Methods and Composer Packages ¶
yii\db\ActiveRecord::findOne()
andyii\db\ActiveRecord::findAll()
inyiisoft/yii2
referenced as CVE-2018-7269. Methods allow SQL injection if input is not prepared properly. Attackers could probably execute arbitrary SQL queries or circumvent access checking methods applied on query level.yii\redis\ActiveRecord::findOne()
andyii\redis\ActiveRecord::findAll()
inyiisoft/yii2-redis
referenced as CVE-2018-8073. Methods allow remote code execution in redis servers lua script environment. Attackers could probably manipulate data on the redis server.yii\elasticsearch\ActiveRecord::findOne()
andyii\elasticsearch\ActiveRecord::findAll()
inyiisoft/yii2-elasticsearch
referenced as CVE-2018-8074. Methods may allow injecting different search condition than desired or cause an error response from the elasticsearch server.
Is my Application Affected? ¶
This vulnerability affects all releases of the 2.0.x branch. It is fixed in Yii 2.0.15. For versions below 2.0.15, we have released two patch versions, 2.0.13.2 and 2.0.12.1, which apply the fix to 2.0.13.1 and 2.0.12 respectively. Users of 2.0.14, can upgrade to 2.0.15, there are no other changes made in this release.
Not Affected Code ¶
The methods findOne()
and findAll()
accept a single argument, which can be scalar or array. If the calling code ensures that a scalar is passed
or if client inputs cannot modify the array's structure, your application is not affected by this issue.
The following code examples are not affected by this issue (examples shown for findOne()
are valid also for findAll()
):
// yii\web\Controller ensures that $id is scalar
public function actionView($id)
{
$model = Post::findOne($id);
// ...
}
// casting to (int) or (string) ensures no array can be injected (an exception will be thrown so this is not a good practise)
$model = Post::findOne((int) Yii::$app->request->get('id'));
// explicitly specifying the colum to search, passing a scalar or array here will always result in finding a single record
$model = Post::findOne(['id' => Yii::$app->request->get('id')]);
Affected Code ¶
The following code however is vulnerable, an attacker could inject an array with an arbitrary condition and even exploit SQL injection:
$model = Post::findOne(Yii::$app->request->get('id'));
For the above example, the SQL injection part is fixed with the patches provided in this release, but an attacker may still be able to search records by different condition than a primary key search and violate your application business logic. So passing user input directly like this can cause problems and should be avoided.
How do I Upgrade? ¶
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 are using yii2-redis
extension:
composer require "yiisoft/yii2-redis":"~2.0.8"
If you are using yii2-elasticsearch
extension:
composer require "yiisoft/yii2-elasticsearch":"~2.0.5"
Update: We have since released further patches to lower the impact of the BC break introduced by the security fix, so you get versions 2.0.15.1, 2.0.13.3 and 2.0.12.2 from the above.
Upgrading isn't Enough! ¶
Upgrading Yii addresses the SQL injection but doesn't make findOne()
and findAll()
safe in general. Check all usages of findOne()
and findAll()
in your application. Also note, that where()
and filterWhere()
never escape column names, so if you need to pass a variable as a column name, make sure it is safe.