Php 有多安全';是数字';反对sql注入

Php 有多安全';是数字';反对sql注入,php,sql,security,oracle10g,sql-injection,Php,Sql,Security,Oracle10g,Sql Injection,我用的都是数字,我从用户那里得到的唯一输入是一个带有学生ID号的表单 我最近在阅读有关SQL注入的文章,想知道是否有必要采取以下预防措施 目前我有: if(is_numeric($_POST['sid']){ $sid = $_POST['sid']; $query = "select * from student where sid='".$sid."'"; // More Code... } 我读到的更安全 if(is_numeric($_POST['sid

我用的都是数字,我从用户那里得到的唯一输入是一个带有学生ID号的表单

我最近在阅读有关SQL注入的文章,想知道是否有必要采取以下预防措施

目前我有:

if(is_numeric($_POST['sid']){
     $sid = $_POST['sid']; 
     $query = "select * from student where sid='".$sid."'";
     // More Code...
}
我读到的更安全

if(is_numeric($_POST['sid']){
     $sid = (int) $_POST['sid'];
     $query = "select * from student where sid='".$sid."'";
     // More Code...
}
一个版本真的比另一个更安全吗?有人如何绕过“是数字的”?

还有,这会比我现在拥有的安全性低吗

if(is_numeric($_POST['sid']){
     $query = "select * from student where sid='".$_POST['sid']."'";
     // More Code...
}
所以,我想我真正想问的是,这些代码块中的一个是否真的比另一个更安全



编辑:很抱歉,我没有提前说明,但我使用的是oracle 10g数据库,而不是mysql。使用oci_connect()

您为什么要回答这些问题,询问如何清理输入,以便从外部数据构建SQL语句从外部数据生成SQL语句是危险的。

与其浪费时间担心如何想出另一个半途而废的“解决方案”,不如停下来穿上程序员的裤子,开始使用准备好的语句和绑定变量

以下是一个奇妙的答案,可以帮助您开始:

您还可以查看其他示例


在我看来,您仍然可以使用Oracle:或通过PDO编写准备好的语句和绑定变量。我不支持这两个版本。您应该使用PDO或mysqli对查询进行适当的参数化。例如:

$query = "SELECT * FROM student WHERE sid = ?";
$stmt = $pdo->prepare($query);
$stmt->execute(array($_POST['sid']));
在这种情况下,该漏洞是在数据库访问级别而不是在应用程序级别处理的。这可能看起来没什么大不了的,但是有人可能会将查询移到
if
语句之外,并且不正确地使用该查询(您可能会认为有人也可以重写易受攻击的查询,但这并不是您的错)

还可以使用类型绑定值

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

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

假设您不知道
是如何工作的。或者,您不知道它的逻辑或实现将来是否会发生变化。或者你没有对它进行足够的测试。或者它的文档缺少一些非常具体但重要的注释

总之,有一天可能会发生
返回的是数值
TRUE
,但在SQL中使用数据是不安全的

但是,如果您在检查输入数据后没有停止,而是根据输入创建了新的数据段,那么您肯定可以说出您的数据是什么,不是什么。在本例中,它肯定是一个整数值,而不是其他值。(虽然
is_numeric
也适用于浮点值,但您知道吗?您是否打算这样做?否?)


再举一个例子:如果您的输入是十六进制、八进制或二进制表示法的字符串,
is_numeric
将返回
TRUE
,但您的数据库可能甚至不支持这种特定的表示法(例如,MySQL不支持八进制),因此,您将无法获得预期的结果。

您了解这些代码块的含义吗?两者都不比另一个更安全,但是您最好使用绑定参数。@YourCommonSense我相信我了解,我认为它们在理论上都是一样的。。。但是假设可能会导致问题,这就是为什么我想和其他人核实你是否理解或问这个问题。然而,理解总是比简单的“是”或“否”好。看,
(int)
在这里是毫无用处的。但实际上没有类型SET我没有使用mysql数据库实际上,我使用的是oracle数据库10g,使用的是oci_connect。。。我认为这两种方法都不行…“大程序员裤子”>\u我没有使用mysql数据库,我使用的是oci\u connect和oracle database 10g。@Arian:在我看来,你仍然可以使用oracle:或通过PDO@AndyLester来做准备语句和绑定变量。你能把它们添加到你的答案中吗。。。所以我可以将其标记为已回答?任何值得一试的数据库驱动程序实现都支持绑定变量和准备好的语句。如果您使用的驱动程序实现不是这样的,那么请将其删除。马上。