【问题标题】:Possible SQL injection dropping a table with stored procedure?可能的 SQL 注入删除带有存储过程的表?
【发布时间】:2012-02-12 11:25:48
【问题描述】:

鉴于这个 MySQL 存储过程:

CREATE PROCEDURE customer.`getCustomers5`(
sdf varchar(1000)
)
BEGIN

set @se  = concat('select * from customer.customertbl where id=', sdf);


PREPARE stm1 from @se;

EXECUTE  stm1;

END;

即使调用此存储过程的前端使用 PDO 参数/数据绑定,是否可以将 SQL 注入到此存储过程中?

我需要在调用之前动态构建一个查询(动态 where 子句)。

如果可以进行SQL注入,有什么方法可以解决这个问题吗?

【问题讨论】:

  • stackoverflow.com/questions/60174/…。简而言之,使用 PDO,您应该是安全的。 aaand php.net/manual/en/pdo.prepared-statements.php
  • @SergeyBenner 看来你没有得到问题。
  • -1 提出了一个模糊的问题,结果是“不,我不是这个意思,代码完全不同”。
  • 在您的示例代码中,如果您改为这样做 CREATE PROCEDURE customer.getCustomers5(sdf varchar(1000)) BEGIN select * from customer.customertbl where id=sdf; END; 将无法进行 SQL 注入。但是是的,动态查询需要参数化,否则单独的 SP 不会提供任何防止 sql 注入的保护。

标签: php mysql sql sql-injection


【解决方案1】:

您只是错误地使用了准备好的语句。
您必须绑定参数,而不是连接它们。

DELIMITER // 
CREATE PROCEDURE customer.`getCustomers5`(sdf varchar(1000)) 
BEGIN 
  PREPARE stm1 from 'select * from customer.customertbl where id=?'; 
  SET @a = sdf;
  EXECUTE stm1 using @a; 
END//
DELIMITER ;

【讨论】:

  • 我要做的SQL语句是动态的,参数个数不确定。在这种情况下, set @a 方法将不起作用。我想我仍然需要构建 SQL@Application 级别。
  • 对不起,伙计,但您的评论看起来很荒谬。 set @a 方法确实使用了 stm 变量,这显然不是动态语句。如果您需要动态创建 SQL - 没问题。使用占位符而不是值创建准备好的 SQL。没什么大不了的。您唯一需要做的就是学习和倾听。
【解决方案2】:

如果你的参数是 varchar 并且你发送一个字符串,那么是的,这是可能的,因为即使你使用 PDO,它仍然是一个 ANY 字符串。

您应该将 sdf 定义为您的 id 类型(它是整数吗?如果不是,请将其设为整数!)然后 PDO 参数将被转义并避免 SQL 注入。

一个好的做法是避免在存储过程中创建动态查询并在您的应用程序中构建查询。

【讨论】:

  • 是的,Id 是整数,我只是在测试限制。还有一个问题,如果涉及到很多sql语句,是不是合并到存储过程或者应用级别比较好?
  • 存储过程没问题。但是你必须小心你所有的锁/锁等待等等。
  • 如果您要执行许多 SQL 语句以计算单个结果,最好将其合并到一个存储过程中。这样,应用程序就不需要进行多次查询并将数据保存在本地以供进一步处理。因此,尝试创建尽可能复杂的查询,以便在数据库服务器上进行所有计算,您可以将它们放入存储过程中以便于访问/维护。您仍然应该避免在存储过程中创建动态查询,可能会添加更多参数或创建更多过程以匹配每个场景。
  • 好的,我想我将创建我所有的动态查询@应用程序级别并使用参数绑定来绑定它们。除此之外,它将转到 SP。
  • “PDO 参数将被转义”是什么意思?如果 id 是字符串类型呢?
猜你喜欢
  • 2018-10-06
  • 1970-01-01
  • 2018-06-09
  • 2013-05-03
  • 2016-05-30
  • 1970-01-01
  • 2020-05-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多