SQL 语句 where 子句连等

2018-10-22 12:16:18 +08:00
 whoami9894

昨天测试一个网站登录框 user=admin'='admin'-- &passwd=admin 绕过验证了。本地尝试时对连等的行为有点不理解

mysql> select * from users;
+----+-----------+----------+
| id | username  | password |
+----+-----------+----------+
|  1 | admin     | admin    |
|  3 | guest     | abcdefg  |
|  2 | anonymous | 123456   |
+----+-----------+----------+
3 rows in set (0.00 sec)

mysql> select * from users where username='admin'='admin';
+----+-----------+----------+
| id | username  | password |
+----+-----------+----------+
|  3 | guest     | abcdefg  |
|  2 | anonymous | 123456   |
+----+-----------+----------+
2 rows in set, 1 warning (0.00 sec)

mysql> select * from users where username='admin'='guest';
+----+-----------+----------+
| id | username  | password |
+----+-----------+----------+
|  3 | guest     | abcdefg  |
|  2 | anonymous | 123456   |
+----+-----------+----------+
2 rows in set, 1 warning (0.00 sec)

mysql> select * from users where username='admin'='a';
+----+-----------+----------+
| id | username  | password |
+----+-----------+----------+
|  3 | guest     | abcdefg  |
|  2 | anonymous | 123456   |
+----+-----------+----------+
2 rows in set, 1 warning (0.00 sec)

mysql> select * from users where username='admin'='1';
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | admin    | admin    |
+----+----------+----------+
1 row in set (0.00 sec)

mysql> select * from users where username='admin'='2';
Empty set (0.00 sec)

这里的解析逻辑是怎样的?

2711 次点击
所在节点    程序员
18 条回复
lichao
2018-10-22 12:25:18 +08:00
被 SQL 注入了
lichao
2018-10-22 12:26:57 +08:00
请使用 WHERE user = @user and passwd = @passwd 的参数化查询方式
jzmws
2018-10-22 12:43:06 +08:00
防止 sql 注入最基本的防护
whoami9894
2018-10-22 12:55:36 +08:00
@lichao
@jzmws
....我当然知道是注入,我就是做安全的,我是不明白 where 字句连等是怎么查询出数据的
lichao
2018-10-22 13:29:00 +08:00
@whoami9894 做安全的怎么会不知道 -- 后面是注释
lichao
2018-10-22 13:31:00 +08:00
@whoami9894 哦,那明白你意思了
loading
2018-10-22 13:35:39 +08:00
拼接字符串,实际拼进去就知道了。
lichao
2018-10-22 13:45:39 +08:00
select * from users where name = 0; 这个出来的结果也很奇怪,MySQL 好奇怪
lichao
2018-10-22 13:48:35 +08:00
PostgreSQL 这种语句就完全不合法
zjsxwc
2018-10-22 13:50:12 +08:00
mysql 本来就能连等:



mysql> select (2=2=2);
+---------+
| (2=2=2) |
+---------+
| 0 |
+---------+
1 row in set (0.00 sec)

mysql> select (2=2=true);
+------------+
| (2=2=true) |
+------------+
| 1 |
+------------+
1 row in set (0.00 sec)

mysql> select (2=2=1);
+---------+
| (2=2=1) |
+---------+
| 1 |
+---------+
1 row in set (0.00 sec)
lichao
2018-10-22 13:53:49 +08:00
@zjsxwc 这是 feature 还是 bug ?
jjwjiang
2018-10-22 13:56:47 +08:00
跟 JS 语法类似,连等先判断头两个,变成了 true 或者 false
kev17
2018-10-22 13:57:46 +08:00
(user= "a" ) = "b"
会选出最终结果为 true 的行
例如
```

mysql> select * from users where username='admin'='admin';
+----+-----------+----------+
| id | username | password |
+----+-----------+----------+
| 3 | guest | abcdefg |
| 2 | anonymous | 123456 |
+----+-----------+----------+
2 rows in set, 1 warning (0.00 sec)
```
结果
( 1 ) 第一步 username='admin'的记录返回 1,第二步 true = 'admin' 返回 0,这种记录不会被选择出来

( 2 ) 第一步 username <> 'admin'的记录返回 0,第二步 false = 'admin' 返回 1,这种记录会被选择出来
frazy
2018-10-22 14:11:05 +08:00
楼上正解~
1 就是 true,其他都是 false
whoami9894
2018-10-22 15:30:17 +08:00
@kev17
```sql
mysql> select * from users where false='admin';
+----+-----------+----------+
| id | username | password |
+----+-----------+----------+
| 1 | admin | admin |
| 3 | guest | abcdefg |
| 2 | anonymous | 123456 |
+----+-----------+----------+
3 rows in set, 1 warning (0.05 sec)

mysql> select * from users where true='admin';
Empty set, 1 warning (0.00 sec)
```

SQL 在 bool 和 str 之间比较的行为好奇怪,0='admin'返回 true

这样的话就解释通了
tsparrot
2020-04-25 11:21:41 +08:00
mysql> select * from users;
+----+-----------+----------+
| id | username | password |
+----+-----------+----------+
| 1 | admin | admin |
| 3 | guest | abcdefg |
| 2 | anonymous | 123456 |
+----+-----------+----------+
3 rows in set (0.00 sec)

mysql> select * from users where username='admin'='admin';
+----+-----------+----------+
| id | username | password |
+----+-----------+----------+
| 3 | guest | abcdefg |
| 2 | anonymous | 123456 |
+----+-----------+----------+
2 rows in set, 1 warning (0.00 sec)
楼主你好,请问你帖子里的这个查询返回的结果里为什么会有数据呢( username='admin'返回 1,而 where 1 = ‘str’不是相当于 where 0 吗 为什么会返回数据呢
whoami9894
2020-04-25 12:41:28 +08:00
@tsparrot
'guest'='admin'='admin' => ('guest'='admin')='admin'
'guest'='admin' => 0
0='admin' => 1
所以查出所有 username != 'admin'的记录
tsparrot
2020-04-28 19:39:00 +08:00
@whoami9894 哦哦明白了,谢谢楼主

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/499793

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX