遵循哪种方法来防止 SQL 在 MySql 存储过程中注入

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 的单个记录。 so conclused that method1 is prone to sql injection 所以不要遵循这个方法,因为它的动态查询 & 建议不要在存储过程中编写动态查询。

方法 2、方法 3 有效并给出了单个用户记录,这意味着此查询不易 sql 注入。

大多数开发人员建议

method4 遵循此方法以防止 sql 在存储过程中注入。但是我的 实时项目在存储过程中包含 20 到 30 个查询(insert/update/delete),因此编写准备好的语句 for all 很费时间。

所以指导我遵循哪个方法,方法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 语法,也不用作标识符,因此可以简单地在查询中使用,如上所示。

这假设您的 table 没有自己的同名列 bIntSelfId。如果是这样,该标识符的使用将是不明确的。建议将您的参数命名为与您将使用该变量查询的 table 的任何列明显不同。使用用户定义的变量或查询参数也可以避免歧义。