- PVSM.RU - https://www.pvsm.ru -
Сегодня мы выпускаем обновления Yii для нескольких последних версий 2.0.x и официальных расширений поддержки нереляционных баз данных для исправления найденных уязвимостей. Патчи исправляют проблему в методах слоя ActiveRecord: findOne()
и findAll()
, которые могут допустить SQL инъекцию [1], если входящие данные не подготовлены должным образом.
Мы рассматриваем это как уязвимость в Yii потому что документация для этих методов не содержала явного предупреждения о том, что в некоторых случаях передача нефильтрованых пользовательских данных может быть опасной. Мы благодарим Analitic1983 [2] (GitHub [3]) за обнаружение этой уязвимости.
Проблема относится в большей степени не к самому фреймворку, а к документации по использованию данных методов в приложении. Мы обновили документацию и дополнительно привели примеры кода, который может быть опасен. Однако, обновление документации не исправит приложения, в которых разработчики уже используют методы findOne()
и findAll()
небезопасно. Чтобы избежать наихудшего сценария – SQL инъекции, мы также изменили поведение этих методов и добавили принудительную фильтрацию входящих данных, которая ограничивает перечень возможных имён столбцов списком свойств модели ActiveRecord.
Исправление, хоть и убирает подавляющее большинство проблем, не исправляет их все, потому дальше в статье мы детально рассмотрим, какой код уязвим и что нужно сделать, чтобы обезопасить себя.
yiidbActiveRecord::findOne()
и yiidbActiveRecord::findAll()
в пакете yiisoft/yii2
, чему присвоен номер уязвимости CVE-2018-7269. Методы допускают SQL инъекцию [1], если входящие данные недостаточно отфильтрованы. Атакующий может выполнить произвольный SQL запрос или обойти условия фильтрации, установленные на уровне выполняемого запроса.yiiredisActiveRecord::findOne()
и yiiredisActiveRecord::findAll()
в пакете yiisoft/yii2-redis
, чему присвоем номер уязвимости CVE-2018-8073. Методы допускают удалённое выполнение кода [4] на сервере Redis в виде LUA скриптов. Атакующий может выполнять произвольный LUA код и изменять данные на стороне сервера.yiielasticsearchActiveRecord::findOne()
и yiielasticsearchActiveRecord::findAll()
в пакете yiisoft/yii2-elasticsearch
, чему присвоем номер уязвимости CVE-2018-8074. Методы допускают внедрение условий поиска, не предусмотренных разработчиком.Уязвимость касается всех релизов Yii2 и исправляется в версии 2.0.15. Для версий до 2.0.15 мы релизим два патч-обновления: 2.0.13.2 и 2.0.12.1, который применяют исправление к 2.0.13.1 и 2.0.12 соответственно. Пользователи версии 2.0.14 могут обновиться до версии 2.0.15, так как никаких других изменений в релизе не содержится.
Методы findOne()
и findAll()
принимают один аргумент, который может быть скаляром или массивом. Если код, который вызывает этот метод гарантирует, что переданное значение – скалярно, или что структура передаваемого массива не может быть изменена снаружи — ваше приложение НЕуязвимо. Следующие примеры кода НЕ подвержены данной уязвимости. Примеры вызова findOne()
также валидны и для метода findAll()
.
// yiiwebController гарантирует, что $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')]);
Однако, следующий код – УЯЗВИМ, и атакующий может составить запрос, позволяющий выполнить поиск про произвольному столбцу, или даже SQL инъекцию:
$model = Post::findOne(Yii::$app->request->get('id'));
Данное обновление исправляет возможность внедрения SQL инъекции, но атакующий всё ещё может выполнить поиск по столбцам отличным от первичного ключа, что может нарушить бизнес-логику приложения.
Мы выпускаем обновление безопасности для трёх последних релизов Yii2: 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()
and filterWhere()
никогда не экранируют имена столбцов, потому если вам необходимо использовать переменную, полученную от пользователя в виде названия столбца – убедитесь, что вы делаете это безопасно.
Автор: SilverFire
Источник [5]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/bezopasnost/275769
Ссылки в тексте:
[1] SQL инъекцию: https://en.wikipedia.org/wiki/SQL_injection
[2] Analitic1983: https://habrahabr.ru/users/analitic1983/
[3] GitHub: https://github.com/analitic1983
[4] удалённое выполнение кода: https://en.wikipedia.org/wiki/Remote_code_execution
[5] Источник: https://habrahabr.ru/post/351652/?utm_campaign=351652
Нажмите здесь для печати.