MYSQL有关False注入的隐式类型转换

分享 · 笔记 703 字 大概 2 分钟 1,332 次

timg.jpg

引入

这是一个数据表的内容
2020-07-31T02:25:17.png

select * from admin where username=false;
等同 
select * from admin where username=0;

2020-07-31T02:27:38.png
为什么username=false或者0 会返回“所有数据”呢?

官方有关文档

这就涉及了MYSQL的隐式类型转换,先来看看官方(机翻)文档

以下规则描述比较操作的转换方式:

如果一个或两个参数是 ,则比较的结果为 ,但 -安全<=>相等比较运算符除外。因为 ,结果为真。无需转换。NULLNULLNULLNULL <=> NULL

如果比较操作中的两个参数都是字符串,则它们被比较为字符串。

如果两个参数都是整数,则它们被比较为整数。

如果不与数字进行比较,十六进制值将被视为二进制字符串。

如果其中一个参数是TIMESTAMP 或 DATETIME 列,另一个参数是常量,则在执行比较之前,常量将转换为时间戳。这样做是更有利于ODBC。这不是为IN() 的参数完成的。为了安全起见,在进行比较时始终使用完整的日期时间、日期或时间字符串。例如,若要在使用日期或时间值的"介于两者之间"时获得最佳结果,请使用CAST()将值显式转换为所需的数据类型。

来自表或表的单行子查询不被视为常量。例如,如果子查询返回要与 DATETIME 值比较的整数,则比较将作为两个整数进行。整数不会转换为时态值。若要将操作数与DATETIME 值进行比较,请使用CAST()将子查询值显式转换为DATETIME。

如果其中一个参数是十进制值,则比较取决于另一个参数。如果另一个参数是十进制值或整数值,则参数与十进制值进行比较;如果另一个参数是浮点值,则参数将比较为十进制值。

在所有其他情况下,参数被比较为浮点(实数)数字。例如,字符串和数值操作数的比较作为浮点数的比较进行。

原理

根据官方文档,如果我是字符串和数字比较,需要将字符串转为浮点数,这很明显会转换失败。
我们来看一下warning
2020-07-31T02:36:41.png
现在可以很好理解之前为什么username=false或者0会导致返回数据。
因为这里会将数据转换为浮点数比较,但是字符串转换会出问题,从而返回false使得false=false或者0从而为true得到结果。

注意的点

  • 如果字符串开头是非数字的字符,那么转换为数字就是0。
  • 如果字符串开头是数字的时候会从数字部分截断,转换为数字,不会为false。
  • 如果字符串中都是数字,那么转换为数字就是整个字符串对应的数字。
文章目录
END

本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。

发表感想