“is_numeric”对sql注入有多安全

时间:2021-08-17 13:02:13

I use is_numeric for everything, the only input I get from users is a form with an Student ID number....

我使用is_numeric一切,唯一的输入我的用户是一个窗体,带有一个学生ID号....

I recently was reading up on SQL Injections and was wondering if the following precaution is necessary?

我最近一直在阅读SQL注入,我想知道是否有必要采取以下预防措施?

Currently I have:

目前我有:

if(is_numeric($_POST['sid']){
     $sid = $_POST['sid']; 
     $query = "select * from student where sid='".$sid."'";
     // More Code...
}

What I've read is safer

我所读到的更安全

if(is_numeric($_POST['sid']){
     $sid = (int) $_POST['sid'];
     $query = "select * from student where sid='".$sid."'";
     // More Code...
}

Is one version really safer than the other? How would someone bypass 'is_numeric'?

一个版本真的比另一个更安全吗?如何绕过is_numeric ?

Also, would this be any less safe than what I currently have?

而且,这会比我现在的安全吗?

if(is_numeric($_POST['sid']){
     $query = "select * from student where sid='".$_POST['sid']."'";
     // More Code...
}

So, I guess what I am really asking, is if one of these code blocks is truly safer than another one

我想我真正想问的是,这些代码块中是否有一个比另一个更安全


EDIT: Sorry I didn't state this early but I am using oracle 10g database, not mysql. With oci_connect();

编辑:抱歉我没有这么早说,但是我使用的是oracle 10g数据库,不是mysql。与oci_connect();

3 个解决方案

#1


8  

Why are you going through these questions asking about how you can sanitize your inputs so that you can build SQL statements from outside data? Building SQL statements from outside data is dangerous.

为什么要问这些问题,关于如何对输入进行消毒,以便从外部数据构建SQL语句?从外部数据构建SQL语句是危险的。

Rather than wasting your time worrying about how you can come up with another halfway thought out "solution", stop and put on your Big Programmer Pants and start using prepared statements and bound variables.

不要浪费你的时间去担心你怎样才能想出一个有一半想法的“解决方案”,停下来,穿上你的大程序员的裤子,开始使用准备好的语句和绑定变量。

Here is a fantastic answer that will get you started: How can I prevent SQL injection in PHP?

这里有一个奇妙的答案可以让您开始:如何防止PHP中的SQL注入?

You can also check http://bobby-tables.com/php for other examples.

您还可以查看http://bobbytables /php以获得其他示例。

Looks to me like you can still do prepared statements and bound variables with Oracle: http://php.net/manual/en/function.oci-bind-by-name.php or through PDO http://php.net/manual/en/pdostatement.bindparam.php

在我看来,您仍然可以使用Oracle来做准备语句和绑定变量:http://php.net/manual/en/function.oci-bin-name.php或通过PDO http://php.net/manual/en/pdostatement.bindparam.php。

#2


5  

I would not endorse either version. What you should be using is properly parameterized queries with PDO or mysqli. For example:

我不会支持任何一个版本。您应该使用带有PDO或mysqli的参数化查询。例如:

$query = "SELECT * FROM student WHERE sid = ?";
$stmt = $pdo->prepare($query);
$stmt->execute(array($_POST['sid']));

In this case the vulnerability is handled at the database access level and not at the application level. It may not seem like a big deal, but someone could move the query outside of the if statement and improperly use the query (you could make the argument that someone could also rewrite a vulnerable query, but that would be less your fault).

在这种情况下,漏洞是在数据库访问级别而不是应用程序级别处理的。这看起来并不是什么大问题,但是有人可以将查询移到if语句之外,并不恰当地使用查询(您可以提出这样的论点,即有人也可以重写脆弱的查询,但这不是您的错)。

You can also bind values with types.

还可以用类型绑定值。

$stmt = $pdo->prepare($query);
$stmt->bindValue(1, (int)$_POST['sid']);

#3


5  

As a rule of thumb, it is not safe enough to just check the data, you should always preprocess the data before using it.

根据经验,仅仅检查数据是不够安全的,您应该在使用数据之前对数据进行预处理。

Let’s say you don’t know all the internals of how the is_numeric works. Or you don’t know if its logic or its implementation will change in future. Or you did not test it heavily enough. Or its documentation lacks some very specific but important note.

假设您不知道is_numeric的工作原理。或者你不知道它的逻辑或实现在未来是否会改变。或者你没有做足够的测试。或者它的文档缺少一些非常具体但重要的注释。

All in all, one day it just might happen that is_numeric returned TRUE but the data is not safe to be used in SQL.

总之,有一天is_numeric可能会返回TRUE,但是在SQL中使用数据并不安全。

However, if you did not stop after checking input data, but instead created new piece of data based on input, you can definitely say what this data of yours is and what it isn’t. In this case, it is definitely an integer value and nothing else. (While is_numeric also works for float values, did you know that? Did you intend that? No?)

但是,如果您在检查输入数据之后没有停止,而是基于输入创建了新的数据块,那么您可以明确地说出您的数据是什么,它不是什么。在这种情况下,它肯定是一个整数值,没有别的。(is_numeric也适用于浮点值,您知道吗?你意愿吗?没有?)

And just another example: if your input is a string in hexadecimal, octal or binary notation, is_numeric will return TRUE, but your database might not even support this particular notation (MySQL does not support octal, for instance), so you will not get expected results.

再举一个例子:如果输入是十六进制、八进制或二进制符号的字符串,is_numeric将返回TRUE,但是您的数据库甚至可能不支持这个特殊的符号(例如,MySQL不支持八进制),所以您不会得到预期的结果。

#1


8  

Why are you going through these questions asking about how you can sanitize your inputs so that you can build SQL statements from outside data? Building SQL statements from outside data is dangerous.

为什么要问这些问题,关于如何对输入进行消毒,以便从外部数据构建SQL语句?从外部数据构建SQL语句是危险的。

Rather than wasting your time worrying about how you can come up with another halfway thought out "solution", stop and put on your Big Programmer Pants and start using prepared statements and bound variables.

不要浪费你的时间去担心你怎样才能想出一个有一半想法的“解决方案”,停下来,穿上你的大程序员的裤子,开始使用准备好的语句和绑定变量。

Here is a fantastic answer that will get you started: How can I prevent SQL injection in PHP?

这里有一个奇妙的答案可以让您开始:如何防止PHP中的SQL注入?

You can also check http://bobby-tables.com/php for other examples.

您还可以查看http://bobbytables /php以获得其他示例。

Looks to me like you can still do prepared statements and bound variables with Oracle: http://php.net/manual/en/function.oci-bind-by-name.php or through PDO http://php.net/manual/en/pdostatement.bindparam.php

在我看来,您仍然可以使用Oracle来做准备语句和绑定变量:http://php.net/manual/en/function.oci-bin-name.php或通过PDO http://php.net/manual/en/pdostatement.bindparam.php。

#2


5  

I would not endorse either version. What you should be using is properly parameterized queries with PDO or mysqli. For example:

我不会支持任何一个版本。您应该使用带有PDO或mysqli的参数化查询。例如:

$query = "SELECT * FROM student WHERE sid = ?";
$stmt = $pdo->prepare($query);
$stmt->execute(array($_POST['sid']));

In this case the vulnerability is handled at the database access level and not at the application level. It may not seem like a big deal, but someone could move the query outside of the if statement and improperly use the query (you could make the argument that someone could also rewrite a vulnerable query, but that would be less your fault).

在这种情况下,漏洞是在数据库访问级别而不是应用程序级别处理的。这看起来并不是什么大问题,但是有人可以将查询移到if语句之外,并不恰当地使用查询(您可以提出这样的论点,即有人也可以重写脆弱的查询,但这不是您的错)。

You can also bind values with types.

还可以用类型绑定值。

$stmt = $pdo->prepare($query);
$stmt->bindValue(1, (int)$_POST['sid']);

#3


5  

As a rule of thumb, it is not safe enough to just check the data, you should always preprocess the data before using it.

根据经验,仅仅检查数据是不够安全的,您应该在使用数据之前对数据进行预处理。

Let’s say you don’t know all the internals of how the is_numeric works. Or you don’t know if its logic or its implementation will change in future. Or you did not test it heavily enough. Or its documentation lacks some very specific but important note.

假设您不知道is_numeric的工作原理。或者你不知道它的逻辑或实现在未来是否会改变。或者你没有做足够的测试。或者它的文档缺少一些非常具体但重要的注释。

All in all, one day it just might happen that is_numeric returned TRUE but the data is not safe to be used in SQL.

总之,有一天is_numeric可能会返回TRUE,但是在SQL中使用数据并不安全。

However, if you did not stop after checking input data, but instead created new piece of data based on input, you can definitely say what this data of yours is and what it isn’t. In this case, it is definitely an integer value and nothing else. (While is_numeric also works for float values, did you know that? Did you intend that? No?)

但是,如果您在检查输入数据之后没有停止,而是基于输入创建了新的数据块,那么您可以明确地说出您的数据是什么,它不是什么。在这种情况下,它肯定是一个整数值,没有别的。(is_numeric也适用于浮点值,您知道吗?你意愿吗?没有?)

And just another example: if your input is a string in hexadecimal, octal or binary notation, is_numeric will return TRUE, but your database might not even support this particular notation (MySQL does not support octal, for instance), so you will not get expected results.

再举一个例子:如果输入是十六进制、八进制或二进制符号的字符串,is_numeric将返回TRUE,但是您的数据库甚至可能不支持这个特殊的符号(例如,MySQL不支持八进制),所以您不会得到预期的结果。