当前位置: 首页> 最新文章列表> 使用mysqli_result时未处理SQL注入,导致查询结果异常怎么办?

使用mysqli_result时未处理SQL注入,导致查询结果异常怎么办?

M66 2025-05-28

在使用PHP进行MySQL数据库操作时,开发者经常会借助mysqli扩展中的相关函数来执行查询并处理结果集。例如,mysqli_query()配合mysqli_result对象使用,可以方便地获取查询结果。然而,如果在构造SQL语句时未对输入参数进行适当的处理,就容易引发SQL注入问题,进而导致查询结果异常、数据泄露甚至系统被攻破。

一、问题场景示例

假设你有一个查询用户信息的页面,代码如下:

<?php
$conn = new mysqli("localhost", "root", "password", "mydb");

$username = $_GET['username']; // 来自用户输入
$sql = "SELECT * FROM users WHERE username = '$username'";

$result = $conn->query($sql);

if ($result && $result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
        echo "用户: " . $row["username"] . ",邮箱: " . $row["email"] . "<br>";
    }
} else {
    echo "未找到用户";
}
$conn->close();
?>

如果用户输入了如下URL:

https://m66.net/user.php?username=admin' OR '1'='1

则SQL语句将变为:

SELECT * FROM users WHERE username = 'admin' OR '1'='1'

这将绕过身份验证条件,返回所有用户的记录。

二、查询结果异常的原因分析

使用mysqli_result对象处理结果集时,返回的数据取决于SQL语句的执行结果。如果语句被注入非法条件,导致结果集中包含了非预期的数据,程序逻辑将出现偏差:

  • 误判条件:如上例中,逻辑判断$result->num_rows > 0为真,但实际上返回的可能是全部数据。

  • 数据泄漏:攻击者可以构造条件读取其他用户的隐私信息。

  • 后续操作混乱:若接着根据结果做权限判断、修改记录等操作,后果将更加严重。

三、解决办法

1. 使用预处理语句(Prepared Statements)

通过使用prepare()bind_param(),可以彻底防止SQL注入:

<?php
$conn = new mysqli("localhost", "root", "password", "mydb");

$username = $_GET['username'];
$stmt = $conn->prepare("SELECT * FROM users WHERE username = ?");
$stmt->bind_param("s", $username);
$stmt->execute();

$result = $stmt->get_result();
if ($result && $result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
        echo "用户: " . $row["username"] . ",邮箱: " . $row["email"] . "<br>";
    }
} else {
    echo "未找到用户";
}

$stmt->close();
$conn->close();
?>

使用预处理语句后,参数会自动进行转义和类型检查,从源头防止了注入。

2. 对用户输入进行过滤

虽然不能替代预处理,但作为安全保障的补充,应对所有用户输入进行必要的验证。例如:

$username = filter_input(INPUT_GET, 'username', FILTER_SANITIZE_STRING);

或自定义过滤逻辑,拒绝非法字符和关键词。

3. 统一封装数据库访问层

为了避免开发人员在不同模块中重复犯错,建议将数据库访问逻辑封装成统一的类或函数,内部始终使用预处理方式,并禁止拼接SQL语句。

四、小结

mysqli_result本身不会引发SQL注入问题,但如果搭配未转义的SQL语句使用,将会在查询阶段埋下严重隐患。只要涉及用户输入,无论看似多么无害的查询操作,都必须使用预处理语句。

切记:**不要信任任何输入,哪怕只是一个用户名。**在m66.net等线上服务中,如果忽略了这些基本安全措施,轻则数据异常,重则造成系统崩溃与数据泄漏。

采取合理防护手段,从代码层面杜绝SQL注入,是每一位PHP开发者不可推卸的责任。

  • 相关标签:

    SQL