“mysqli_real_escape_string”是否足以避免 SQL 注入或其他 SQL 攻击?[复制]

Is "mysqli_real_escape_string" enough to avoid SQL injection or other SQL attacks? [duplicate]

提问人:xRobot 提问时间:9/4/2015 最后编辑:GumboxRobot 更新时间:7/15/2021 访问量:19111

问:

这是我的代码:

  $email= mysqli_real_escape_string($db_con,$_POST['email']);
  $psw= mysqli_real_escape_string($db_con,$_POST['psw']);

  $query = "INSERT INTO `users` (`email`,`psw`) VALUES ('".$email."','".$psw."')";

有人可以告诉我它是否安全,或者它是否容易受到SQL注入攻击或其他SQL攻击?

php mysql 安全 sql 注入

评论

1赞 Ayelis 7/19/2018
我不明白怎么回事。mysqli_real_escape_string() 是一个与 mysql_real_escape_string() 完全不同的函数......也许大多数人在2015年都不知道?

答:

18赞 Scott Arciszewski 9/5/2015 #1

有人可以告诉我它是否安全,或者它是否容易受到SQL注入攻击或其他SQL攻击?

不。正如 uri2x 所说,请参阅绕过 mysql_real_escape_string() 的 SQL 注入

防止 SQL 注入的最佳方法是使用预准备语句。它们将数据(参数)与指令(SQL 查询字符串)分开,并且不会为数据留下任何污染查询结构的空间。预准备语句解决了应用程序安全性的一个基本问题

对于不能使用预准备语句的情况(例如),为每个特定目的使用非常严格的白名单是保证安全性的唯一方法。LIMIT

// This is a string literal whitelist
switch ($sortby) {
    case 'column_b':
    case 'col_c':
        // If it literally matches here, it's safe to use
        break;
    default:
        $sortby = 'rowid';
}

// Only numeric characters will pass through this part of the code thanks to type casting
$start = (int) $start;
$howmany = (int) $howmany;
if ($start < 0) {
    $start = 0;
}
if ($howmany < 1) {
    $howmany = 1;
}

// The actual query execution
$stmt = $db->prepare(
    "SELECT * FROM table WHERE col = ? ORDER BY {$sortby} ASC LIMIT {$start}, {$howmany}"
);
$stmt->execute(['value']);
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);

我认为上述代码不受 SQL 注入的影响,即使在晦涩难懂的边缘情况下也是如此。如果您使用的是 MySQL,请确保关闭模拟准备。

$db->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);

评论

0赞 j_allen_morris 7/7/2021
说“这是最好的方法”并不能回答“这够了吗?
3赞 Scott Arciszewski 7/15/2021
答案是否定的。我回答的第一句话是“看这个例子”,这证明这还不够。
3赞 But those new buttons though.. 4/7/2022
@ScottArciszewski - 您给出的引文是关于哪个 afaik 与 .虽然你的建议还不错,但我认为这个答案不正确。十多年来,我一直在使用用户表单输入进行查询,尽管有数千次(数百万?)次观察到的注入尝试,但没有一次成功。如果你认为它不安全,我想看一个演示。mysql_real_escape_string()mysqli_real_escape_string()mysqli_real_escape_string()
0赞 Muneer 8/29/2022
始终最好使用当今可用的最佳实践。你永远无法保证明天的任何事情,因为今天就足够了。
0赞 Daniel Bengtsson 12/22/2022
如前所述,这是解决错误的函数。mysql_real_escape_string被废除了,因为它有漏洞。之后是 mysqli_real_escape_string()。这是一个误导性的答案