1

几年来我一直在使用准备好的插入语句,并假设它正确绑定参数或会给出错误,但它似乎不是因为以下 php 绑定并插入没有任何错误的记录,而是将应该是 int 的字符串更改为零. 因此,可以防止 SQL 注入攻击,但最终会在表中得到虚假记录。例如:

    $q = "INSERT INTO `table` (id1, id2) VALUES (?, ?)";
    $stmt = mysqli_stmt_init($dbc);
    $stmt->prepare($q);
    $id1 = 'aaaaaaa';
    $id2= 'aaaaaaa';
    $result = $stmt->bind_param('ii', $id1, $id2);
    echo '<p>' . $result . '</p>'; // Trying to bind a string to an int returns true! 
    echo $dbc->error; // nothing
    $stmt->execute(); // inserts record changing $id2 to zero but auto-increments primary key $id1
    echo $dbc->error; // nothing

这是在带有 Apache/2.2.14、PHP/5.3.1 和 MySQL 5.1.41 的 Xampp 环境中运行的。谁能告诉我发生了什么?

4

2 回答 2

0

我肯定不是专家,但乍一看。你有:

$id1 = 'aaaaaaa';
$id2= 'aaaaaaa';
$result = $stmt->bind_param('ii', $id1, $id2);

事情是你的'ii'参数说你将绑定整数!事实上你的$id1and$id2是字符串。对于字符串,您应该使用:

$result = $stmt->bind_param('ss', $id1, $id2);
于 2014-01-09T09:24:04.763 回答
0

$stmt->bind_param() 不会检查给定变量的特定类型,它只会将它们转换为指定的类型。并且您的字符串 'aaaaaaa' 被转换为一个 int 值:0。这就是 php 的做法。

如果您的变量包含有用/正确的值,则数据库插入语句是错误的检查位置。如果您的验证有效,请在之前执行此操作,并且仅尝试插入它们。

要对 int 进行验证,您可以使用 php 函数 is_numeric() 或 is_int()。

于 2014-01-09T09:35:02.553 回答