下面的代码非常简单。 PHP使用POST从表单中收集字符串,然后寻找并修剪并运行preg_replace函数,该函数将去除除单引号或连字符以外的所有特殊字符。切记,整个代码可以正常运行,而无需在正则表达式中使用引号或连字符。
preg_replace("/[^\w\s'-]/", '', $raw_lemurName);
然后将这些干净变量插入数据库中。 Apache / 2.4.37。 MariaDB。
当我将lemurName设为“ Diademed Sifaka <>!”之类的字符串时,它将起作用,并返回“ Diademed Sifaka”。
但是,当我使用包含单引号的字符串作为字符串时,例如“ Coquerel的Sifaka”,操作将无法完成,并且不会插入任何信息。
我已经单独测试了regex表达式,它可以正常工作,似乎当您开始涉及SQL和数据库时,它便停止工作。
值得注意的是:
有什么想法吗?
非常感谢。
$raw_lemurName = isset($_POST['lemurName']) ? $_POST['lemurName'] : null;
$raw_lemurLat = isset($_POST['lemurLat']) ? $_POST['lemurLat'] : null;
$raw_family = isset($_POST['family']) ? $_POST['family'] : null;
//下面的正则表达式似乎把东西弄乱了
$c_lemurName = trim(preg_replace("/[^\w\s'-]/", '', $raw_lemurName));
$c_lemurLat = strtolower(trim(preg_replace('/[^\w\s]/', '', $raw_lemurLat)));
$c_family = trim(preg_replace('/[^\w\s]/', '', $raw_family));
if (isset($_POST['submit'])) {
$query1 = "INSERT INTO `lemurs` (`id`, `lemur`, `latin`, `family`) VALUES (NULL, '$c_lemurName','$c_lemurLat','$c_family')";
$run_query = mysqli_query($connection, $query1);
if($run_query){
echo "Data has been inserted";
} else {
echo "Operation Unsuccessful";
}
header("location: index.php");
return;
}
答案 0 :(得分:1)
这是标准的SQL注入问题。问题源于将这些变量添加到查询中的方式:
$query1 = "INSERT INTO `lemurs` (`id`, `lemur`, `latin`, `family`) VALUES (NULL, '$c_lemurName','$c_lemurLat','$c_family')";
仔细考虑这里发生的事情,您所做的只是将字符串并置,因此,如果$c_lemurName
是'
-那么您的SQL将变为:
[...] VALUES (NULL, ''', '[...]
实际上,这实际上使您可以进行所谓的“注入攻击”。基本上,恶意用户可以将$c_family
设置为... ');drop table lemurs;--
之类的东西-您现在正在执行一条insert语句,然后执行一个drop table语句,其余的SQL则为注释。 / p>
有几种方法可以解决这个问题,最常用的方法是查看参数化查询-对于mysqli库,这必须通过准备好的语句来完成。 PHP docs page上有一个示例。
答案 1 :(得分:0)
也替换第二个参数区域中的单引号。用这个。
preg_replace("/[^\w\s'-]/", "", $raw_lemurName);
希望它能工作
答案 2 :(得分:0)
您将$ c_lemurLat和$ c_family用于正则表达式: “ / [^ \ w \ s] /”
这将正确过滤单引号。
对于$ c_lemurName,您正在使用: “ / [^ \ w \ s'-] /”
这不会删除单引号。
删除'-,即可正常运行。