提问人:Arrow 提问时间:6/11/2021 最后编辑:Bill KarwinArrow 更新时间:6/11/2021 访问量:211
遵循哪种方法来防止 MySql 存储过程中的 SQL 注入
which method to follow to prevent SQL injection in MySql Stored Procedure
问:
嗨,朋友们,我用谷歌搜索了一下,发现其他人使用不同的方法来防止SQL注入。在最终确定之前,我写了下面的存储过程,以遵循我希望得到你们的建议。我应该遵循哪种方法。
下面是我的存储过程示例,我在其中编写了不同的方法
CREATE DEFINER=`root`@`localhost` PROCEDURE `spTestSQLInjection`(pSelfId VARCHAR(100),bIntSelfId BIGINT(20))
BEGIN
SET @sSelfId = pSelfId;
-- Method:1
-- below code is for injection
SET @selectQuery = CONCAT('select * from userProfile where userId = ',@sSelfId);
PREPARE stmt FROM @selectQuery;
EXECUTE stmt ;
DEALLOCATE PREPARE stmt;
-- Method:2
-- injection doesent affect below code
select * from userProfile where userId = @sSelfId;
-- Method:3
select * from userProfile where userId = bIntSelfId;
-- Method:4
SET @sSelectQuery=
'select * from userProfile where userId = ? ';
PREPARE stmtQuery FROM @sSelectQuery;
EXECUTE stmtQuery USING @sSelfId;
DEALLOCATE PREPARE stmtQuery;
END
在Workbench中执行以下存储过程:
1)调用 spTestSQLInjection('231', 231);
结果:当我传递正确的数据时,结果集会给出所有 4 方法的单个用户数据。
2)调用 spTestSQLInjection('231 OR 1=1', 231);
结果:当我传递“231 OR 1=1”数据时,结果集给出方法 1 的所有用户数据和方法 2、3、4 的单条记录。 所以得出结论,Method1 容易发生 SQL 注入,所以不要遵循这种方法,因为它的动态查询 &建议不要在存储过程中编写动态查询。
Method2、Method3 有效并给出了单用户记录,这意味着此查询不容易发生 SQL 注入。
大多数开发人员建议 Method4 遵循此规则,以防止在存储过程中注入 SQL。但我的 Live Project 在一个存储过程中包含 20 到 30 个查询(插入/更新/删除),因此编写准备好的语句 因为一切都很耗时。
因此,请指导我遵循哪种方法、方法 2、方法 3 或方法 4
提前感谢您,任何帮助将不胜感激。
答:
方法 2、3 和 4 可以避免 SQL 注入,但方法 3 是最简单的解决方案。
CREATE DEFINER=`root`@`localhost` PROCEDURE `spTestSQLInjection`(pSelfId VARCHAR(100), bIntSelfId BIGINT(20))
BEGIN
-- Method:3
select * from userProfile where userId = bIntSelfId;
END
无需创建用户定义的变量,因为过程参数已经是变量。bIntSelfId
在这种情况下,无需使用参数或预准备语句,因为变量仅被视为标量值。它不需要修改任何 SQL 语法,也不需要用作标识符,因此可以简单地在查询中使用,如上所示。
这假定您的表没有自己的同名列。如果是这样,那么使用该标识符将是模棱两可的。建议将参数与将使用该变量查询的任何表列区分开来。使用用户定义的变量或查询参数也可以避免歧义。bIntSelfId
评论