Как избежать риска внедрения SQL-кода при динамическом создании таблицы? - PullRequest
0 голосов
/ 26 апреля 2019

Вот простая процедура, которая создает таблицу из предоставленного пользователем ввода:

PROCEDURE `hackProcedure`(
IN tab_name VARCHAR(63))
BEGIN

IF (tab_name REGEXP '^[A-Za-z0-9 ]+$')
THEN
    SET @StB = CONCAT('CREATE TABLE tab_name
                      (id INT(10) PRIMARY KEY NOT NULL UNIQUE AUTO_INCREMENT,
                      name VARCHAR(45),
                      guid VARCHAR(36));');
    PREPARE statementB FROM @StB;
    EXECUTE statementB;
    DEALLOCATE PREPARE statementB;
ELSE
    -- SIGNAL some error;
END IF;
#END

Перед созданием таблицы я проверяю, что пользовательский ввод содержит только буквенно-цифровые значения, так что, насколько я понимаю, плохой человек пытается сделать SQLвнедрение этой процедуры не может быть успешным, поскольку невозможно закомментировать оставшуюся часть запроса или добавить другие столбцы.Это безопасно или мне не хватает чего-то?

1 Ответ

2 голосов
/ 26 апреля 2019

Это не уязвимо, потому что код, который вы нам показали, использует буквальное значение для имени таблицы, а не параметра.Я думаю, что вы хотели сделать это:

CONCAT('CREATE TABLE ',  tab_name, '
                  (id INT(10) PRIMARY KEY NOT NULL UNIQUE AUTO_INCREMENT,
                  name VARCHAR(45),
                  guid VARCHAR(36));');

А что если я вызову вашу функцию с ...

dummy (id INT NOT NULL); DROP TABLE mysql.users; CREATE TABLE dummy2

?

Это не удастся, потому чтоТочка с запятой и скобки будут отвергнуты регулярным выражением, но это далеко не надежное решение.

Добавление обратных кавычек вокруг имени таблицы (если они запрещены регулярным выражением) - это небольшое улучшение.

 CONCAT('CREATE TABLE `',  tab_name, '`
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...