繁体   English   中英

如何验证整数值以避免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;

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

更新:尽管我在最初的问题中已经说过,但是大多数人都强调了参数化查询的有用性。 无疑,这是避免SQL注入的最有效方法。 但是当我们可以简单地验证整数数值时; 恕我直言,无需参数化。

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

$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);

如果您需要经验丰富的建议,则必须改变主意。 完全可以

实际上,您最关心的事情是世界上最微不足道的事情。 您可以使用一种或另一种方式,但不会有丝毫差别。 没有“最可靠”的方式。 那只是做相同事情的几种方法。

另一方面,“无需参数化”是一种严重的幻想。
参数化查询只有在整个站点中明确使用且无例外的情况下,才能发挥任何作用。 一种例外会破坏所有防御能力。

更不用说参数化查询可以使您的生活变得轻松得多。
准备好的语句并不是某些发烧友在此站点上传播的丑陋代码。 实际上,这是编写安全代码的快速而简洁的方法。
我说,那把cetver十几行代码就可以在短短的一个来完成:

$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);

与您当前的手工铸造相当。

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

智人坐

您可以使用mysql_real_escape_string()这个函数来分隔特殊字符,但是您可以做的很好以保护sqli攻击。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM