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

为何PHP登录表单无法触发SQL Injection?无防护却失效

Why Your Basic SQL Injection Isn't Working on This Login Form

我完全懂你的困惑——特意做了个没防护的登录表单,结果常用的注入payload却死活不管用,一直跳凭据错误。咱们一步步扒代码、理逻辑,把问题找出来。

1. SQL逻辑优先级直接坑了你的Payload

先看你用的admin'OR'1'='1这个payload,假设你把它填在用户名框,密码随便输个比如test,咱们拼一下最终生成的SQL语句:

你的代码里的SQL模板是:

$sql="SELECT * FROM users WHERE username='$username' AND password='$password'";

替换后会变成:

SELECT * FROM users WHERE username='admin'OR'1'='1' AND password='test'

这里的核心问题是SQL逻辑运算符的优先级:AND的优先级比OR高,所以这条SQL会被数据库解析成:

SELECT * FROM users WHERE (username='admin') OR ('1'='1' AND password='test')

也就是说,只有两种情况会匹配到数据:

  • 数据库里真的有个叫admin的用户(不管密码是什么);
  • 你输的密码刚好是test(因为'1'='1'永远为真,这部分等价于直接判断密码)。

如果你的数据库里没有admin用户,或者你输的密码不对,这条SQL就会返回0行,自然触发“凭据错误”。

怎么调整Payload才能生效?

你需要修改payload来改变逻辑优先级,或者直接注释掉后面的密码判断:

  • 方案1:用户名填admin' OR '1'='1' -- (注意最后有空格),拼接后的SQL会变成:
    SELECT * FROM users WHERE username='admin' OR '1'='1' -- ' AND password='test'
    
    后面的AND password='test'会被SQL注释掉,整个条件变成username='admin' OR '1'='1'(永远为真),就能匹配到用户数据。
  • 方案2:用户名直接填' OR '1'='1' -- ,不管密码填什么,都能直接让条件成立。

2. 可能存在的隐形防护因素

虽然你说没设置防护,但有些隐形的转义机制可能在生效:

自动转义的问题

如果你的myconnection.php里开启了字符集转义(比如mysqli_set_charset($db, 'utf8mb4');其实会自动处理部分转义?不对,准确说如果用了mysqli_real_escape_string但你没注意到,或者服务器上开启了早已废弃的magic_quotes_gpc(旧PHP环境可能存在),那么你输入的单引号会被自动转义成\',导致payload失效。

比如输入admin'OR'1'='1会被转义成admin\'OR\'1\'=\'1,拼接后的SQL变成:

SELECT * FROM users WHERE username='admin\'OR\'1\'=\'1' AND password='test'

这时候单引号被转义,payload就变成了普通字符串,没法破坏SQL结构。你可以加一行调试代码看看实际的$username值:

var_dump($username); // 放在$username=$_POST['username'];后面

如果输出里的单引号变成了\',说明存在自动转义。

数据库表为空

如果你的users表压根没有任何数据,那不管SQL条件写得多么离谱,都会返回0行,自然触发错误提示。你可以先手动插一条测试数据:

INSERT INTO users (username, password) VALUES ('testuser', 'testpass');

再测试注入,看看会不会生效。

3. 代码里的小bug(不影响注入,但值得修正)

顺便提几个和注入无关但影响功能的小问题:

  • $login_user=$_POST["$username"]; 这里应该写成$_POST['username'],你现在是用$username的值作为键去取POST数据,会导致错误;
  • 你的JavaScript提示有语法错误:echo "<script='text/javascript'>$message</script>"; 应该改成echo "<script type='text/javascript'>alert('$message');</script>";,否则不会弹出提示;
  • 登录成功跳转后要加exit;或者die();,避免后面的代码继续执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:39:57