在 MySQL 5.6 数据库上,我构建了这个简单的表并插入了一行:
CREATE TABLE `users` (
`username` varchar(64) DEFAULT NULL,
`password` varchar(64) DEFAULT NULL
);
INSERT INTO users VALUES ('bob', 'pass');
然后我像这样在 PHP 中设置查询:
$query = "SELECT * from users where username=\"".$username."\" and password=\"".$password."\"";
当$username
和$password
都等于""="
时,结果查询是SELECT * from users where username="""=""and password="""=""
。用于查询之前设置的表时,返回表中的行。
问题是,MySQL 如何评估该查询,使其认为该查询有效且 WHERE 语句为真?假设所有双引号都与最近的未采用的相邻双引号匹配,我希望查询被解释成这样,看起来应该被认为是乱码:
SELECT * from users where username=""
"="
" and password="
""
=
""
这是 MySQL 5.6 DB 上此行为的示例:http://sqlfiddle.com/#!9/02e606/2
最佳答案
这是因为 MySQL 允许 ""
作为 \"
的替代。
mysql> select '"foo"' = """foo""", '"foo"' = "\"foo\"", 'foo' = """foo""";
+---------------------+---------------------+-------------------+
| '"foo"' = """foo""" | '"foo"' = "\"foo\"" | 'foo' = """foo""" |
+---------------------+---------------------+-------------------+
| 1 | 1 | 0 |
+---------------------+---------------------+-------------------+
1 row in set (0.00 sec)
在您的具体情况下:
SELECT * from users where username="""="" and password="""=""
将与(如果我在脑海中正确解析)相同:
SELECT * from users where (username='"="" and passsword="') = ""
三向相等性测试在语法上是正确的,但未按预期进行评估
mysql> select 'a' = 'a' = 'a';
+-----------------+
| 'a' = 'a' = 'a' |
+-----------------+
| 0 |
+-----------------+
因为它解析为 (a=a)=a
-> true=a
-> false
-- 评论跟进@juan:
mysql> select 'a'='a'='a', 'a'='a'='b', 'a'='b'='a', 'b'='a'='a', 'b'='b'='a';
+-------------+-------------+-------------+-------------+-------------+
| 'a'='a'='a' | 'a'='a'='b' | 'a'='b'='a' | 'b'='a'='a' | 'b'='b'='a' |
+-------------+-------------+-------------+-------------+-------------+
| 0 | 0 | 1 | 1 | 0 |
+-------------+-------------+-------------+-------------+-------------+
这是不直观的,因为
mysql> select 'a'=('a'='b'), ('a'='a')='b', true='b', 'a'=false;
+---------------+---------------+----------+-----------+
| 'a'=('a'='b') | ('a'='a')='b' | true='b' | 'a'=false |
+---------------+---------------+----------+-----------+
| 1 | 0 | 0 | 1 |
+---------------+---------------+----------+-----------+
--- followup to the followup: again, your original query:
SELECT * from users where username="""="" and password="""=""
将运行为
SELECT * from users where (username='"="" and passsword="') = ""
SELECT * from users where (false) = ""
SELECT * from users where true
因为 mysql 中的 false =""
计算结果为 TRUE,因此所有行都被包括在内,除非您的用户名是 "=""和 password="
.
关于php - 为什么 ""="利用这个 MySQL 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39923935/