繁体   English   中英

针对sql注入的'is_numeric'有多安全

[英]How safe is 'is_numeric' against sql injection

我使用is_numeric作为一切,我从用户那里获得的唯一输入是一个带有学生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...
}

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

此外,这比我现有的安全吗?

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

所以,我猜我真正在问的是,这些代码块中的一个是否真的比另一个更安全


编辑:对不起,我没有提到这个,但我使用的是oracle 10g数据库,而不是mysql。 使用oci_connect();

为什么要通过这些问题询问如何清理输入以便从外部数据构建S​​QL语句? 从外部数据构建S​​QL语句是危险的。

而不是浪费你的时间担心如何能够提出另一个中途考虑“解决方案”,停止并穿上你的大程序员裤子并开始使用预备语句和绑定变量。

这是一个很棒的答案,可以帮助您入门: 如何在PHP中阻止SQL注入?

您还可以查看http://bobby-tables.com/php了解其他示例。

在我看来,你仍然可以使用Oracle做预备语句和绑定变量: http//php.net/manual/en/function.oci-bind-by-name.php或通过PDO http://php.net/手动/ EN / pdostatement.bindparam.php

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

假设你不知道is_numeric如何工作的所有内部结构。 或者您不知道其逻辑或其实现是否会在将来发生变化。 或者你没有足够严重地测试它。 或者它的文档缺少一些非常具体但重要的说明。

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

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

另一个例子:如果你的输入是十六进制,八进制或二进制表示法的字符串, is_numeric将返回TRUE ,但你的数据库可能甚至不支持这种特殊的表示法(例如MySQL不支持八进制),所以你不会得到预期成绩。

我不赞同任何一个版本。 应该使用的是使用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']);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM