You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的PHP登录代码无法触发SQL注入漏洞?

问题分析与解决方案

首先,你遇到的警告是因为SQL查询执行失败了:当mysqli_query()无法执行你的注入语句时,会返回布尔值false,而mysqli_fetch_array()和mysqli_num_rows()都需要传入有效的mysqli_result对象,因此触发了类型不匹配的警告。

第一步:先排查SQL错误原因

要知道你的注入语句到底哪里出问题了,先给代码加个错误检查,这样能直接看到SQL执行的具体错误信息:

$result = mysqli_query($conn,$sql);
// 添加这行错误检查
if (!$result) {
    die("SQL执行错误: " . mysqli_error($conn));
}

添加后再执行注入,就能明确看到语句的语法问题了。

第二步:简化你的注入语句

你用的注入语句太复杂,还存在无效的字符串比较(比如'1' = '1 ',带空格的'1 '和纯'1'是不相等的),反而容易导致SQL语法异常。其实用最简单的注入语句就能达成目的:

在用户名输入框输入:

' OR 1=1 -- 

密码随便填(比如123)。此时拼接后的SQL会变成:

SELECT * FROM users WHERE username = '' OR 1=1 -- ' AND password = '123'

这里的-- 是SQL注释符(注意后面必须有空格),会把后面的' AND password = '123'全部注释掉。最终WHERE条件变成username = '' OR 1=1,这个条件永远为真,会返回users表中所有记录,$count自然会≥1,就能成功登录。

第三步:修正代码的逻辑漏洞

你的代码还有个小问题:$sql的定义在isset($_POST["sbm"])的外面,如果请求里没有sbm参数(虽然表单里有,但极端情况可能出现),$username和$password会是未定义变量,直接导致SQL语法错误。建议把查询逻辑放到isset($_POST["sbm"])的代码块内,并且跳转后加上exit防止后续代码执行:

if($_SERVER["REQUEST_METHOD"] == "POST") {
    if(isset($_POST["sbm"])){
        $username = $_POST['username'];
        $password = $_POST['password'];
        
        $sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
        $result = mysqli_query($conn,$sql);
        
        if (!$result) {
            die("SQL执行错误: " . mysqli_error($conn));
        }
        
        $count = mysqli_num_rows($result);
        
        if($count >= 1) {
            $_SESSION['login_user'] = $username;
            header("location: welcome.php");
            exit; // 跳转后必须终止脚本
        }
    }
}

内容的提问来源于stack exchange,提问作者Riwi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:03:44