为什么这个 sql 是正确的? (sql 注入)
Why this sql is correct? (sql injection)
这是什么意思?
SELECT * from users where password = ''*'';
如果我在 mysql workbench 中检查这个,我只得到 一行 ,尽管我在 table 中有很多用户。
这 select 到底是做什么的?
有趣的问题。让我们看看 ''*''
做了什么。
mysql> select ''*'';
+-------+
| ''*'' |
+-------+
| 0 |
+-------+
让我们创建一些用户:
mysql> select * from users;
+------+-------+
| id | name |
+------+-------+
| 1 | joe |
| 2 | moe |
| 3 | shmoe |
| 4 | 4four |
+------+-------+
并测试我们的查询:
mysql> select * from users where name = ''*'';
+------+-------+
| id | name |
+------+-------+
| 1 | joe |
| 2 | moe |
| 3 | shmoe |
+------+-------+
有趣的是,用户 4 没有被选中!但是让我们试试这个方法:
mysql> select * from users where name = 4;
+------+-------+
| id | name |
+------+-------+
| 4 | 4four |
+------+-------+
那么,我们可以从中推断出什么呢?
''*''
不知何故意味着 0(我对 mysql 字符串运算符不是那么流利,所以让我们把它当作事实);
- MySQL,显然,在这种情况下进行类型转换。因此,如果您针对整数查询 varchar 列,它会尝试将这些字符串转换为整数并查看它是否匹配;
- 您只有一行
password
以 0 或非数字开头。
''*''
是一个乘法:它的两个参数(空字符串)被转换为数值(即0),结果为0。然后等式左边也被转换为数字,有时会是零(当密码不能被评估为非零数字时),有时不是。
有点晦涩难懂,您可以问问自己,这是针对您的情况有意为之还是偶然行为,而实际意图是测试 '*'
。有恶意的用户可能输入了 '*'
作为密码,希望您不受 SQL 注入保护,以便在没有有效密码的情况下进入系统。
- 您始终可以在 SQL 中使用 表达式 。比如SELECT 5-4 AS one 得到1。所以你可以看出这是一个表达式。
- MySQL 是一种松散类型的语言,因此它可以乘以字符串。将它们转换为数字。
'' * ''
让你归零
- 将字符串与数字进行比较时,MySQL 将两者都转换为数字。所以 0 = 'name' 条件会让你为真
这是什么意思?
SELECT * from users where password = ''*'';
如果我在 mysql workbench 中检查这个,我只得到 一行 ,尽管我在 table 中有很多用户。
这 select 到底是做什么的?
有趣的问题。让我们看看 ''*''
做了什么。
mysql> select ''*'';
+-------+
| ''*'' |
+-------+
| 0 |
+-------+
让我们创建一些用户:
mysql> select * from users;
+------+-------+
| id | name |
+------+-------+
| 1 | joe |
| 2 | moe |
| 3 | shmoe |
| 4 | 4four |
+------+-------+
并测试我们的查询:
mysql> select * from users where name = ''*'';
+------+-------+
| id | name |
+------+-------+
| 1 | joe |
| 2 | moe |
| 3 | shmoe |
+------+-------+
有趣的是,用户 4 没有被选中!但是让我们试试这个方法:
mysql> select * from users where name = 4;
+------+-------+
| id | name |
+------+-------+
| 4 | 4four |
+------+-------+
那么,我们可以从中推断出什么呢?
''*''
不知何故意味着 0(我对 mysql 字符串运算符不是那么流利,所以让我们把它当作事实);- MySQL,显然,在这种情况下进行类型转换。因此,如果您针对整数查询 varchar 列,它会尝试将这些字符串转换为整数并查看它是否匹配;
- 您只有一行
password
以 0 或非数字开头。
''*''
是一个乘法:它的两个参数(空字符串)被转换为数值(即0),结果为0。然后等式左边也被转换为数字,有时会是零(当密码不能被评估为非零数字时),有时不是。
有点晦涩难懂,您可以问问自己,这是针对您的情况有意为之还是偶然行为,而实际意图是测试 '*'
。有恶意的用户可能输入了 '*'
作为密码,希望您不受 SQL 注入保护,以便在没有有效密码的情况下进入系统。
- 您始终可以在 SQL 中使用 表达式 。比如SELECT 5-4 AS one 得到1。所以你可以看出这是一个表达式。
- MySQL 是一种松散类型的语言,因此它可以乘以字符串。将它们转换为数字。
'' * ''
让你归零
- 将字符串与数字进行比较时,MySQL 将两者都转换为数字。所以 0 = 'name' 条件会让你为真