我正在尝试从网址获取网页的ID,并使用它从数据库中检索信息。我想确保id是一个长度小于4的整数,如果没有,则重定向到父页面。
if(isset($_GET["id"])) {
$id = (int) $_GET["id"];
// If id is longer than 4 redirect
if(strlen($id) > 4) {
header("Location: /parent.php");
exit;
}
try {
$sth = $dbh -> prepare("SELECT id, title, etc, FROM table WHERE id = :id");
$sth -> bindParam(':id', $id, PDO::PARAM_INT);
$sth -> execute();
} catch(PDOException $e) {
// print $e -> getMessage();
echo "Error";
exit;
}
$feature = $sth -> fetch(PDO::FETCH_ASSOC);
// If query result is empty redirect
if($feature == false) {
header("Location: /parent.php");
exit;
}
$sth = null;
} else { // If id isn't set redirect
header("Location: /parent.php");
exit;
}
我这样做是否安全/正确?我还在处理这类事情,所以我第二次猜测自己。
此外,它似乎按照我的意图工作,除非将id设置为123abc(child.php?id = 123abc),它将其解释为123并仍然加载id 123的信息。因为我正在投类型是它只是忽略了abc部分?我是否应该担心它仍然会加载并且不会重定向到父级?
答案 0 :(得分:2)
您可以使用input filtering来确保传递的标识符确实是一个整数;它是否大于9999应该无关紧要,但也许测试一个正整数是一个好主意:
if (($id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT)) !== false && $id > 0) {
// id was passed and it's a valid integer
} else {
// evil request, die die
}
使用预准备语句已经减轻了潜在的SQL注入攻击,因此代码的其余部分不必更改,但我个人会尝试制作单个故障流而不是四个单独的(但几乎相同的)故障流
答案 1 :(得分:1)
是的,通过将输入转换为整数,您已经规避了任何SQL注入攻击。 通过使用绑定变量,您再次阻止了sql注入攻击。 :)
你在int上使用strlen有点难看,所以我建议检查$ id>虽然你可能不会注意到差异。