3

我正在使用 php 并在 mysql 服务器上运行 sql 查询。为了防止 sql 注入,我使用 mysql_real_escape_string。

我还以下列方式使用 (int) 进行数字转换:

$desired_age = 12;
$query = "select id from users where (age > ".(int)$desired_age.")";
$result = mysql_query($query);

那项工作。

但是,当变量包含较大的数字时,转换它们会失败,因为它们大于 int。

$user_id = 5633847511239487;
$query = "select age from users where (id = ".(int)$user_id.")";
$result = mysql_query($query);
// this will not produce the desired result, 
// since the user_id is actually being cast to int

除了使用 mysql_real_escape_string 之外,还有其他方法可以转换大数(如 BIGINT),什么时候可以防止 sql 注入?

4

6 回答 6

11

如果您自己生成用户 ID,则无需将其转换为 MySQL,因为不会出现 SQL 注入或其他字符串问题。

如果它是用户提交的值,则使用filter_var()(或is_numeric()) 来验证它是数字而不是字符串。

于 2010-07-08T13:50:02.177 回答
3

你可以使用类似的东西:

preg_replace('/[^0-9]/','',$user_id);

替换字符串中的所有非数字符号。但实际上没有必要这样做,只需使用 mysql_real_escape_string() 因为一旦 $query 构建,您的整数值将被转换为字符串。

于 2010-07-08T13:55:44.660 回答
1

验证输入。不要只是简单地逃避它,验证它,如果它是一个数字。有几个 PHP 函数可以解决问题,例如 is_numeric() - 查找变量是数字还是数字字符串

http://www.php.net/is_numeric

于 2010-07-08T13:48:43.600 回答
1

使用服务器端准备好的参数化语句(从而消除对 xyz_real_escape_string() 的需要)和/或将 id 视为字符串。MySQL 服务器具有用于字符串<->数字转换的内置规则,如果您决定更改 id 字段的类型/结构,您也不必更改 php 代码。除非您对(微)优化有具体需求,否则通常不需要让代码对数据库中 id 字段的结构和值范围做出这种假设。

$pdo = new PDO('mysql:...');
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

$stmt = $pdo->prepare('SELECT age FROM users WHERE id=?');
$stmt->execute(array('5633847511239487'));
于 2010-07-08T14:13:27.817 回答
0

经过一些研究,我来到了这样的设置

private function escapeInt($value)
{
    if (is_float($value))
    {
        return number_format($value, 0, '.', ''); // may lose precision on big numbers
    }
    elseif(preg_match('/^-?[0-9]+$/', $value))
    {
        return (string)$value;
    }
    else
    {
        $this->error("Invalid value");
    }
}

浮点数的单独大小写,因为$i = 184467440737095;在 32 位系统上变为浮点数,因此在转换为字符串时会崩溃为科学记数法。
剩下的就是简单的正则表达式

于 2012-12-12T21:41:59.840 回答
0

您甚至可以将变量乘以*1,您可以检查它可以接受的最小值和最大值(因为年龄 bigint 根本不是一个选项......那么为什么甚至允许数字超过您准备的值?还有 PDO随着它的查询准备。

于 2014-04-18T23:40:33.727 回答