Вопрос

Информация об опаном использовании метода Column.Const

Добрый день.

Я занимаюсь аудитами защищенности веб-приложений. В одном из проектов наш заказчик использовал bpm'online. В его конфигурации было выявлено ряд уязвимостей к SQL-инъекции.

Типичный пример уязвимого кода (имена метода и переменных изменены; значение параметра email контролируется пользователем):

using Terrasoft.Core.DB
…
 
private Guid GetUserId(string email)
{
    var select = new Select(Connection)
        .Column("Id")
        .From("Users")
        .Where("Email")
        .IsEqual(Column.Const(email)) as Select;
    return select.ExecuteScalar<Guid>();
}

Данный код использует метод Column.Const для передачи параметра, полученного от пользователя в SQL-запрос. Этот метод осуществляет конкатенацию этого параметра с запросом, не фильтруя специальные символы.

Это позволяет пользователю, контролирующему передаваемый в метод Column.Const параметр, выполнить атаку типа SQL-инъекция. То есть получить доступ ко всей информации в базе данных.

Мы порекомендовали нашему Заказчику использовать Column.Parameter вместо Column.Const в данном случае.

Документация Террасофт не сообщала (на момент публикации) об опасности некорректного примененеия метода Column.Const. В документации на Академии даже содержались некорректные примеры использования.

Я связался с поддержкой Террасофт и изложил проблему. Их позиция - ответственность лежит на разработчиках, но документацию они обещали поправить (и уже частично поправили).

Я полагаю, что многие разработчики могут не знать об этой особенности метода Column.Const, как и разработчики нашего заказчика. По этому я публикую эту информацию здесь, надеюсь это поможет избежать уязвимостей.

Рекомендую вообще не использовать Column.Const, заменить на Column.Parameter, либо делать это крайне осторожно, будучи абсолютно уверенным что в настоящий момент, или при будущих изменениях значение параметра не будет контролироваться пользователем.

Для отслеживания данной проблемы зарегистрирован идентификатор: CVE-2019-15301.

Нравится

1 комментарий

Вообще, в самом Column.Const нет ничего криминального, правильное его использование упомянуто тут в начале статьи:

new Insert(UserConnection)
.Into("Table")
.Values()
    .Set("Column1", Column.Const(1))
    .Set("Column2", Column.Const(1))
    .Set("Column3", Column.Const(1))
.Values()
    .Set("Column1", Column.Const(2))
    .Set("Column2", Column.Const(2))
    .Set("Column3", Column.Const(2))
.Values()
    .Set("Column1", Column.Const(3))
    .Set("Column2", Column.Const(3))
    .Set("Column3", Column.Const(3))
.Execute();

А использование констант вместо параметров ухудшает не только безопасность, но и скорость, поскольку БД должна каждый раз парсить одинаковый запрос, где отличается только значение константы.

Если ещё остались статьи с неправильным применением, нажмите кнопку внизу их и оставьте замечание со ссылкой на эту тему.

А если нашли уязвимость в коде стандартной конфигурации, лучше напишите не здесь, а прямо на почту службы поддержки.

Показать все комментарии