如何验证整数值以避免SQL注入


How to validate integer values to avoid SQL injection?

对于已定义的值类型(如数字),避免SQL注入的最佳方法是验证值;因为与mysqli准备相比,这样做更容易。在PHP中,我们可以通过.来实现这一点

1. if(!is_numeric($value)) {$value=0;}
2. $value=floatval($value);
3. $value=intval($value);
4. $value=$value * 1;

什么是最可靠的?还是更好的主意?

UPDATE:尽管我在最初的问题中已经说过,但大多数人都强调参数化查询的有用性。毫无疑问,这是避免SQL注入的最有效方法。但当我们可以简单地验证一个整数值时;IMHO,没有必要参数化。

对于整数和浮点,如果您不想进行参数化查询,可以使用它。

$clean_number = (int)$value;
$clean_number = (float)$value;

它们实际上将值强制转换为intfloat,这比intval()floatval()快,例如,因为它不承担函数开销。

我更喜欢使用过滤器扩展:

$id = filter_var($id, FILTER_SANITIZE_NUMBER_INT);

您应该明确使用参数化查询。

您可以使用intval()将值强制为整数。避免SQL注入的最可靠方法是使用参数化查询。

$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
try {
    $dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}
$sth = $dbh->prepare('SELECT * FROM table WHERE id = :id');
$sth->bindParam(':id', $id, PDO::PARAM_INT); 
$sth->execute();
$result = $sth->fetchAll(PDO::FETCH_ASSOC);

如果你想要一个经验丰富的建议,你必须改变主意。彻底地

事实上,你最关心的事情是世界上最微不足道的事情。你可以用这样或那样的方式,没有丝毫区别。没有"最可靠"的方法。这只是几种相同的方法。

另一方面,"没有必要参数化"是一种严重的错觉
参数化查询只有在整个网站上明确使用才能发挥作用,无一例外。一个例外会破坏所有的防御。

更不用说参数化查询可以让您的生活轻松很多
准备好的语句并不是一些爱好者在这个网站上传播的丑陋代码。这实际上是编写安全代码的一种快速而简洁的方式
比方说,花了十几行的代码只需一行就可以完成:

$data = $db->getAll("SELECT * FROM table WHERE id = :placeholder:",$id);

并且非常安全
没有难看的手工装订
没有容易出错的手动铸造。

另一个向您展示占位符功能的例子

$sql = "SELECT * FROM table WHERE tstamp BETWEEN ?i AND ?i AND flag=?s AND IN in (?a)";
$data = $db->getAll($sql,$min,$max,$flag,$array_of_ids);

两行。

我不太擅长PDO,但即使没有连接,它也会像一打代码行

$in  = implode(',', array_fill(0, count($array_of_ids), '?'));
$sql = "SELECT * FROM table WHERE tstamp BETWEEN ? AND ? AND flag=? AND id IN ($in)"
$sth = $dbh->prepare($sql);
$stmt->bindValue(1, $min);
$stmt->bindValue(2, $max);
$stmt->bindValue(3, $flag);
foreach ($array_of_ids as $i => $id) {
  $stmt->bindValue(($i+4), $id);
}
$sth->execute();
$result = $sth->fetchAll(PDO::FETCH_ASSOC);

与您当前的手动铸造量相当。

这实际上就是编程的威力
一个人可以编写程序来为他们做所有肮脏的工作
这种方法在这个网站上几乎从未见过。

Sapienti sat

您可以使用此函数mysql_real_eescape_string()来转义特殊字符,但您所做的一切都可以保护sqli攻击。