我使用is_numeric做所有事情,我从用户那里得到的唯一输入是带有学生证号的表格......
我最近正在阅读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();
你为什么要问这些问题,询问如何清理你的输入,以便你可以从外部数据构建SQL语句? 从外部数据构建 SQL 语句是危险的。
与其浪费时间担心如何想出另一个半途而废的"解决方案",不如停下来穿上你的大程序员裤子,开始使用准备好的语句和绑定变量。
这里有一个很棒的答案,可以帮助你入门:如何防止PHP中的SQL注入?
您还可以查看 http://bobby-tables.com/php 以获取其他示例。
在我看来,您仍然可以使用 Oracle 进行预准备语句和绑定变量:http://php.net/manual/en/function.oci-bind-by-name.php 或通过 PDO http://php.net/manual/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']);