如何在php中强制转换bigint来防止sql注入?

发布于 2024-09-09 07:12:04 字数 659 浏览 8 评论 0原文

我正在使用 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注入?

i am using php and running sql queries on a mysql server.
in order to prevent sql injections, i am using mysql_real_escape_string.

i am also using (int) for numbers casting, in the following manner:

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

that work.

But, when the variable contains larger numbers, casting them fails since they are larger than 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

Is there another way to cast large number (like BIGINT), except for the use of mysql_real_escape_string, when is comes to sql injection prevention?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

怪我入戏太深 2024-09-16 07:12:04

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

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

If you are generating the user ID yourself there is no need to cast it for MySQL since there is no chance of SQL injection or other string issues.

If it is a user submitted value then use filter_var() (or is_numeric()) to verify it is a number and not a string.

陪你到最终 2024-09-16 07:12:04

您可以使用类似:

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

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

You could use something like:

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

to replace all non numeric symbols in your string.
But there actually is no need to do so, simply use mysql_real_escape_string() as your integer value will be converted to a string anyway once $query is built.

梦幻的味道 2024-09-16 07:12:04

验证输入。如果它是一个数字,不要只是简单地转义它,而是验证它。有几个 PHP 函数可以做到这一点,例如 is_numeric() - 查找变量是数字还是数字字符串

http://www.php.net/is_numeric

Validate input. Don't just simply escape it, validate it, if it's a number. There're couple of PHP functions which do the trick, like is_numeric() - Finds whether a variable is a number or a numeric string

http://www.php.net/is_numeric

猫腻 2024-09-16 07:12:04

使用服务器端准备好的参数化语句(从而消除对 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'));

Use server-side prepared, parametrized statements (and thus remove the need for xyz_real_escape_string()) and/or treat the id as a string. The MySQL server has built-in rules for string<->number conversions and if you should decide to change to type/structure of the id field you don't have to change the php code as well. Unless you have concrete needs for (micro-)optimization there's usually no need to let the code make this kind of assumptions about the structure and value range of an id field in the database.

$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'));
流年已逝 2024-09-16 07:12:04

经过一番研究后,我

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 位系统上成为浮点数,因此在转换为字符串时会崩溃为科学计数法。
其余部分则使用简单的正则表达式

After some research I've come to such setup

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");
    }
}

Separate case for the floats because $i = 184467440737095; become float on a 32-bit system and thus will crumble to scientific notation when cast to string.
And simple regexp for the rest

小红帽 2024-09-16 07:12:04

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

You can even multiply the variable by *1, you can check it min and max values you can accept (for age bigint is not an option at all... so why even allow numbers more than values you are prepared for?
And there is also PDO with its query preparing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文