SQL Injection в Delphi
Перевод поста SQL Injectionopen in new window
Я понял, что в своём недавнем посте security assumptionsopen in new window пропустил одно важное предположение (сейчас это исправлено):
Предполагайте, что все входные данные могут быть вредоносными.
Сегодня я хочу показать очень общую ошибку, которая может возникнуть во всех языках и SQL базах данных, и то как её можно использовать. Эта ошибка называется внедрение SQL кодаopen in new window. Я слышал, что разработчики предполагают что эта проблема связана только с web-приложениями. Но я видел эту проблему во всех типах приложений которые работают с базой данных.
Сегодняшний пример является VCL приложением использующим FireDAC для доступа к SQLite. Пример можно найти в репозитории security-demoopen in new window на GitHub.
Внедрения SQL имеют место когда вы не используете параметры, из-за этого входные данные имеют возможность изменять вашу команду SQL.
Ниже показан небезопасный путь передать значение из поля ввода в запрос
FDQuery1.SQL.Add('select * from tbl1 where name like ''' + edtSearchTerm.Text +'%''');
FDQuery1.Open;
2
Если я введу следующий текст в edtSearchTerm.text
a ' union select name, sql from sqlite_master --
То я получу список таблиц в база данных, в котором просто увидеть другую таблицу с названием salary
. Затем я могу ввести следующее и получить всю информацию об оплате.
a ' union select name, value from salary --
Ниже показан безопасный способ сделать туже функцию
FDQuery1.SQL.Add('select * from tbl1 where name like :name');
FDQuery1.ParamByName('name').asString := edtSearchTerm.Text + '%';
FDQuery1.Open;
2
3
Теперь я могу снова попытаться произвести внедрение SQL с помощью тех-же строк. И это мне не удаться, так как строки теперь внутри параметра и следовательно не могут изменить оператор SQL. Проблемы легко избежать, но всё же это довольно распространённая ошибка.
Тестирование на внедрения SQL кода очень простое — вы пробуете завершить ввод одиночной или двойной кавычкой. Если вы получаете неожиданные ошибки то у вас есть возможность SQL Injection.
Мы склонны концентрироваться на вводе от пользователя, но API такие как SOAP или REST также могут стать целью SQL Injection. Поэтому я очень осторожно сказал что нужно проверять все входные данные, а не только ввод пользователя.