php - 在 MySQL 中使用绑定(bind)参数作为用户定义的变量是否安全?

标签 php mysql pdo prepared-statement sql-injection

问题

我知道使用准备好的语句可以防止注入(inject) the prepared statement execution consists of two stages: prepare and execute .

好的,但如果将绑定(bind)参数值用作 User-Defined Variables,我真的不明白发生了什么在 MySQL 中。

初始安全绑定(bind)参数过程是否可用于步骤 2 中的执行(以及注入(inject))?

// The user input that may be the target for injection
$userInput = "input";

// STEP 1 -------------------
$q = "SET @param1 = :param1;";  

// Execute query to set mysql user-defined variables
$param = [
'param1'    => $userInput
];

$stmt = $pdo->prepare($q);
$stmt->execute($param);


// STEP 2 -------------------
// Query DB with User-Defined Variables
$q = "
SELECT ...
WHERE 
table.field1 = @param1 OR
table.field2 = @param1 OR
table.field3 = @param1
";

// Query
$stmt = $pdo->query($q);


// STEP 3 -------------------   
// Fetch Data
$row = $stmt->fetch();

我为什么要使用这种方法?

我使用这个来避免多个相似的命名参数,就像下面的例子一样

you cannot use a named parameter marker of the same name more than once in a prepared statement, unless emulation mode is on

来自 manual .维护复杂的查询是一团糟:

$q = "
SELECT ...
WHERE 
table.field1 = :param1_1 OR
table.field2 = :param1_2 OR
table.field3 = :param1_2
";

$param = [
'param1_1'  => $userInput
'param1_2'  => $userInput
'param1_3'  => $userInput
];

$stmt = $pdo->prepare($q);
$stmt->execute($param);

最佳答案

是的,您可以假设用户变量代替查询中的单个标量值,就像绑定(bind)参数占位符一样。它可以有效防止 SQL 注入(inject)。

证明:尝试使用用户变量执行 SQL 注入(inject)。

SET @s = 'Robert''; DROP TABLE Students;--';

SELECT * FROM Students WHERE name = @s;

不会删除表格。它可能什么都不返回,因为没有学生有那个奇怪的长名字(除非你用 Little Bobby Tables 上学)。


但是,我想知道这样的查询是否:

SELECT ...
WHERE 
table.field1 = @param1 OR
table.field2 = @param1 OR
table.field3 = @param1

表示 field1、field2 和 field3 实际上应该是子表中的单个字段。如果您在多个列中搜索相同的值,它可能是一个重复组。例如,如果它是 phone1、phone2、phone3,那么这是一个多值属性,应该存储在子表中多行的一列中。然后您可以使用单个参数进行搜索。

关于php - 在 MySQL 中使用绑定(bind)参数作为用户定义的变量是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50118991/

相关文章:

php - PDO PHP 连接, fatal error

php - 使用 PDO 创建表单搜索

php - #1136 - 列数与第 1 行的值数不匹配

php - 为什么我在调试这个简单的 PDO 脚本时看不到错误?

mysql - 如何根据另一个 SELECT 的值进行 SELECT

PHP MYSQL SELECT 查询参数包含与号(&)

php - 如何在 REGEXP 中使用多个关键字?

php - MySQL 选择表列 31-12-2014 type varchar as date order by date php

php - 在过滤器未运行之前

MYSQL:将自动增量值插入多个列