如何在php中使用bigint来防止sql注入?

时间:2010-07-08 13:45:36

标签: php mysql casting sql-injection bigint

我正在使用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)吗?

6 个答案:

答案 0 :(得分:10)

如果您自己生成用户ID,则无需为MySQL投射,因为没有SQL注入或其他字符串问题。

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

答案 1 :(得分:3)

您可以使用以下内容:

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

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

答案 2 :(得分:1)

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

http://www.php.net/is_numeric

答案 3 :(得分: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'));

答案 4 :(得分: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位系统上变为浮点数,因此在转换为字符串时会崩溃为科学记数法。
其余的简单正则表达式

答案 5 :(得分:0)

您甚至可以将变量乘以*1,您可以检查它可以接受的最小值和最大值(对于年龄bigint根本不是一个选项...所以为什么甚至允许数字超过你的值准备好了吗? 并且还有PDO及其查询准备。