【发布时间】:2019-07-09 16:45:02
【问题描述】:
我想知道这个 sql 查询是否受到 sql-injection 的保护,是否可以,或者我应该修改一些东西。
我尝试从 GET 绑定 id,如果一切正常,我会使用带有该 id 的实际查询。
if(isset($_GET['id']) && $_GET['id'] != null) {
$id = $_GET['id'];
$stmt = $mysqli->prepare('SELECT id FROM maps WHERE id = ?');
$stmt->bind_param('i', $id);
$stmt->execute();
$result = $stmt->get_result();
if (mysqli_num_rows($result) == 1) {
$row = $result->fetch_assoc();
$secid = $row["id"];
} else {
header("LOCATION: index.php");
}
$sql = "SELECT
maps.id,
maps.name,
maps.description,
maps.date,
maps.mcversion,
maps.mapid,
maps.category,
maps.format,
maps.userid,
users.username,
users.rank,
users.verified,
users.mc_username,
(SELECT COUNT(*) FROM likes WHERE likes.mapid = maps.id) AS likes,
(SELECT COUNT(*) FROM downloads WHERE downloads.mapid = maps.id) AS downloads,
(SELECT COUNT(*) FROM subscribe WHERE subscribe.channelid = maps.userid) AS subscribes,
(SELECT COUNT(*) FROM views WHERE views.mapid = maps.id) AS views
FROM maps
INNER JOIN users
ON maps.userid = users.id
WHERE maps.id = '$secid'";
$result = mysqli_query($con,$sql);
if (mysqli_num_rows($result) > 0) {
$row = mysqli_fetch_assoc($result);
} else {
header("LOCATION: index.php");
}
} else {
header("LOCATION: index.php");
}
【问题讨论】:
-
@David 说“这东西存在吗?”这看起来像是一种被误导的方式。最好将这些和
JOIN组合在一起。 -
这个概念本身对 SQL 注入是不安全的,因为您只是从表中获取值并将其直接放入您的 SQL 字符串中。如果表值本身不好(假设您检索了一个名称,例如“O'Connell”,然后按名称进行查找)。相反,您应该始终使用准备好的语句。您已经对
maps进行了查询,因此只需使用大查询字符串并将WHERE maps.id = '$ecid'"替换为WHERE maps.id=?。 -
@SloanThrasher 仅在 50% 的情况下使用它。
-
@SloanThrasher “某种已经验证过的”正是人们在泄露后审计报告中提出的内容。这是弱验证,并且在修复微不足道时会引入不必要的风险。
-
由于第二个查询中使用的 $secid 来自于第一个查询解释了为什么它被称为“Second Order SQL 注入”
标签: php mysql sql sql-injection