提问人:adrianTNT 提问时间:11/26/2022 更新时间:11/26/2022 访问量:88
此函数是否适用于一般清理数据库查询变量?
Would this function work for generally sanitizing db query variables?
问:
我知道大多数人都说只使用准备好的语句,但我有一个网站,里面有很多现有的查询,我需要通过函数方法清理变量。mysqli_real_escape_string()
此外,说的php手册是一个可以接受的替代方案,所以我在这里......mysqli_query()
mysqli_real_escape_string()
我想做这种类型的查询:
$query = sprintf("SELECT * FROM users WHERE user_name = %s",
query_var($user_name, "text"));
$Records = mysqli_query($db, $query) or die(mysqli_error($db));
我想知道以下功能是否有效,我不确定:
- 我还应该在开始时做吗?我在 Adobe Dreamweaver 中使用的一个旧函数可以做到这一点。
stripslashes()
- 是否可以在后面添加引号?
$the_value = "'".$the_value."'";
mysqli_real_escape_string()
- 它有什么明显/大的缺陷吗?
我注意到删除了多个并将其替换为一个,因此 migt 不能很好地用于一般用途,例如,当用户提交可能包含的文本注释或项目描述时,通常可以不在这里使用吗?stripslashes()
\\\\\\
\\\\
stripslashes()
我最担心的是SQL注入,如果提交的数据包含html标签是可以的,因此,我在输出/打印数据时会处理这个问题。
if(!function_exists('query_var')){
function query_var($the_value, $the_type="text"){
global $db;
// do I still need this ?
// $the_value = stripslashes($the_value);
$the_value = mysqli_real_escape_string($db, $the_value);
// do not allow dummy type of variables
if(!in_array($the_type, array('text', 'int', 'float', 'double'))){
$the_type='text';
}
if($the_type=='text'){
$the_value = "'".$the_value."'";
}
if($the_type=='int'){
$the_value = intval($the_value);
}
if($the_type == 'float' or $the_type=='double'){
$the_value = floatval($the_value);
}
return $the_value;
}
}
答:
MySQL / MariaDB中的文本字符串常量以单引号字符开头和结尾。如果文本本身包含引号字符,我们可以通过将其加倍来转义它。因此,名称“O'Leary”在 SQL 语句的文本中如下所示。'
SET surname = 'O''Leary'
这是唯一的规则。如果您的用户使用反斜杠或其他转义方案为您提供数据,您可以使用此处提到的文本字符串表示形式逐字将其提供给 MySql。
不要想太多。但使用仔细调试的转义函数。避免编写自己的错误,因为任何微小的错误都允许 SQL 注入。
评论
SET surname = 'O\'Leary'
stripslashes
mysqli_real_escape_string
''
\'
O'Leary
INSERT INTO 'test' ('name') VALUES ('O\'Leary');
查看PHP函数文档,我发现了一些参考资料,使我决定该函数中不需要这些函数。stripslashes()
https://www.php.net/manual/en/security.database.sql-injection.php
像 addslashes() 这样的泛型函数仅在非常特定的 环境(例如,单字节字符集中的 MySQL 禁用了 NO_BACKSLASH_ESCAPES)所以最好避免它们。
https://www.php.net/manual/en/function.addslashes.php
addslashes() 有时被错误地用于尝试阻止 SQL 注射。取而代之的是特定于数据库的转义函数和/或 应使用准备好的语句。
评论
sprintf()
execute()
x > 10
x > '10'