我有一个使用动态SQL的MySQL存储过程。我们使用动态SQL,因为我们有几个具有相似列的表,我们正在努力使代码尽可能重用。
我关注SQL注入,但标准的攻击字符串似乎不适用于此。此存储过程是否容易受SQL注入影响?如果是这样,有没有更好的方法来写它?
CREATE DEFINER=CURRENT_USER PROCEDURE `sp_lookup`(IN tableName VARCHAR(256))
BEGIN
SET @sql = CONCAT('SELECT id, name, FROM ', tableName, ' ORDER BY name');
PREPARE stmt FROM @sql;
EXECUTE stmt;
END
答案 0 :(得分:3)
存储过程不会添加任何额外的安全性。
它不会阻止SQL注入,您需要使用预准备语句。
另一种方法是使用表white-listing,这意味着如果不运行查询,则首先检查表是否与现有表匹配。
答案 1 :(得分:0)
只有当用户提供的文本字符串连接到SQL语句而没有足够的转义时,才会发生SQL注入。由于您的表名不是由用户提供,而是由程序员提供,因此您没有遇到麻烦。
但是你不应该这样做。数据库引擎最好有明确的语句,因此可以正确优化它们,而不必在每次调用时重新解析SQL。
答案 2 :(得分:0)
表名应该用“ticks”包围,并且有任何刻度转义,如下所示:
CREATE DEFINER=CURRENT_USER PROCEDURE `sp_lookup`(IN tableName VARCHAR(256))
BEGIN
SET @sql = CONCAT('SELECT id, name FROM `', REPLACE(tableName, '`', '\`'), '` ORDER BY name');
PREPARE stmt FROM @sql;
EXECUTE stmt;
END
尽管目前缺乏这些,但您的漏洞似乎相当低;根据{{3}}“预处理语句的SQL语法不支持多语句”
答案 3 :(得分:0)
孤立地我会说是的,这个存储过程可能很脆弱,但漏洞可能无关紧要。 的重要性在于tablename
参数的值是否来自可信赖的来源。
如果您检查一个标准攻击字符串,"您将看到攻击者正在尝试完成您的SQL查询,然后使用其他查询进行跟踪。为此,攻击者必须能够直接修改拼接到查询中的字符串。
如果您使用此SP的方式使得恶意用户无法直接修改tablename
的值,则您没有SQL注入漏洞。
我希望这是有道理的。