Вот простая процедура, которая создает таблицу из предоставленного пользователем ввода:
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-инъекцию в этой процедуре, не может быть успешным, потому что невозможно закомментировать оставшуюся часть запроса или добавить другие столбцы, Это безопасно или мне не хватает чего-то?
Он не уязвим, потому что код, который вы нам показали, использует буквальное значение для имени таблицы, а не параметр. Я думаю, что вы хотели сделать это:
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, ''