Добрый день.
Я занимаюсь аудитами защищенности веб-приложений. В одном из проектов наш заказчик использовал 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.
Нравится
Вообще, в самом 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();
А использование констант вместо параметров ухудшает не только безопасность, но и скорость, поскольку БД должна каждый раз парсить одинаковый запрос, где отличается только значение константы.
Если ещё остались статьи с неправильным применением, нажмите кнопку внизу их и оставьте замечание со ссылкой на эту тему.
А если нашли уязвимость в коде стандартной конфигурации, лучше напишите не здесь, а прямо на почту службы поддержки.