正如我在很多帖子中看到的那样,存储过程中的动态SQL容易受到SQL注入的攻击。但是,如果我们使用之前的PDO和准备好的声明,这仍然是不安全的吗?
示例:
CREATE PROCEDURE my_sp(
IN in_var VARCHAR(32)
)
BEGIN
DECLARE query VARCHAR(255);
SET @query = CONCAT("SELECT * FROM my_table WHERE my_column = '",in_var,"' LIMIT 1;";
PREPARE stmt FROM @query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;
$dbh = new PDO( $connection_params );
$dbh->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND,"SET NAMES utf8mb4");
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$sql = "CALL my_sp( :in_var )";
$stmt = $dbh->prepare( $sql );
$stmt->execute( array( ':in_var' => $_POST['in_var'] ) );
编辑:
很抱歉再次重新提出这个问题,但有些事情我还不清楚。
示例:
/* php */
$in_var = " ' OR '1' = '1'; -- ";
/*If I try with PDO without prepared statement and
without calling a stored procedure THAT WORK ... the injection is succesful*/
$sql = "SELECT * FROM my_table WHERE my_column = '$in_var' ";
/*With prepared statement NO RESULTS no errors so no injection*/
$sql = "SELECT * FROM my_table WHERE my_column = :in_var ";
/*Now if I call a Stored Procedure with prepared statement in PDO PHP
but in the procedure I have not used prepared statement that return NO RESULTS no errors so no injection
*/
$sql = "CALL my_sp( :in_var )";
/*If I call the Stored procedure without prepared statement in PDO PHP
that got an PDO error:
Syntax error or access violation: 1064 ...
But seem that injection was not succesful
*/
$sql = "CALL my_sp( '$in_var' )";
我是初学者,我知道我的逻辑可能不太好,但似乎在PDO中使用预处理语句时,注入不会发生,尽管它不会在程序中再次使用预处理语句。
答案 0 :(得分:1)
是的,当然。
如果in_var
等于' UNION SELECT password from admins --
?
为避免这种情况,您不应使用 cargo cult 准备好的声明,而应使用真实的声明,用占位符替换您的变量。
SET @query = CONCAT("SELECT * FROM my_table WHERE my_column = ? LIMIT 1;");
PREPARE stmt FROM @query;
EXECUTE stmt USING @in_var;