我可以配置MySQL的类型转换来考虑0!=’foo’吗?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了我可以配置MySQL的类型转换来考虑0!=’foo’吗?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4598字,纯文字阅读大概需要7分钟。
内容图文
![我可以配置MySQL的类型转换来考虑0!=’foo’吗?](/upload/InfoBanner/zyjiaocheng/896/58740a7973084ca486422033e600db8f.jpg)
This article指出MySQL存在以下安全问题:
USERS
id | email | password_reset_token
1 | one@example.com | QTlXww)uV!Hdg3U6aGwKV2FPvAqzVgPx
2 | two@example.com | CZor5t7WbX#LTeqiG3v@6f3@z#)BfK*n
在这里,我们有一个很好的,随机的令牌,用户必须证明他们有重置他们的帐户.但是用户设法提交0的重置令牌,因此我们运行此查询:
SELECT * FROM `users` WHERE `email` = 'one@example.com' AND `password_reset_token` = 0
MySQL将令牌VARCHAR转换为INT以进行比较.它认为VARCHAR不以数字开头等于0.因此,攻击者可以匹配任何非数字字符串并接管帐户.
即使重置令牌启动某些数字,情况也不会好多少. MySQL在进行此比较时会忽略所有字符,但会忽略初始数字,因此它认为12blahblah3blah4等于12,这使猜测成倍增加.
我可以配置MySQL不进行这种类型转换吗?例如,如果它将INT转换为VARCHAR而不是反之亦然,则此攻击不起作用.
注意
如果查询以“0”而不是0运行,则不起作用.本文根据Ruby on Rails对XML的接受程度讨论了这个漏洞,其中type = integer属性说服Rails在查询中发送实际的整数.
该错误已在Rails中修补;它现在将所有请求参数转换为字符串,因此它永远不会使用整数构建查询.但我仍然认为MySQL应该可配置以防止这种情况发生.
解决方法:
但问题是你提供了一个数字值,没有引用,所以MySQL试图将比较的另一面强制转换为DOUBLE,以便将它与你提供的数字参数进行比较…这样你就得到了一个0相当于0.
mysql> select 'foo' = 0;
+-----------+
| 'foo' = 0 |
+-----------+
| 1 |
+-----------+
1 row in set, 1 warning (0.00 sec)
mysql> show warnings;
+---------+------+-----------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: 'foo' |
+---------+------+-----------------------------------------+
1 row in set (0.00 sec)
如果在字符串上下文中提供0,则计算结果为false.
mysql> select 'foo' = '0';
+-------------+
| 'foo' = '0' |
+-------------+
| 0 |
+-------------+
1 row in set (0.00 sec)
因此,您可以使用一个选项来避免这种行为,将输入值转换为CHAR …大多数情况下,它已经是……但如果没有,则按照您的预期进行评估.
mysql> select 'foo' = cast(0 as char);
+-------------------------+
| 'foo' = cast(0 as char) |
+-------------------------+
| 0 |
+-------------------------+
1 row in set (0.00 sec)
更新,以更全面地回答这个问题:
Can I configure MySQL not to do this kind of typecasting?
不,似乎没有任何办法可以通过配置来避免这种情况 – 只能通过显示你的潜在数字字符串的显式 – 转换为一个字符串,你说这是不可能的,因为你是使用ORM.最可能的地方,如果这样的事情存在,将是SQL Server Mode,并且在进行比较时,这些选项都不会改变这种行为.
在Bug #63112中对这种隐式转换进行了一些讨论:
SELECT orange > banana;
Is this true or false? Well .. most often a banana is longer than an orange. So if lenght is the criteria the above statement is false. But most often an orange is heavier than a banana, so if weight is the criteria the above statement is true.
When comparing different types (orange versus banana, string versus integer) some ‘criteria’ or ‘rule’ will have to be used. When MySQL compares different datatypes they are [both] cast to DOUBLE internally before comparison. The integer “1” casts to the double “1” – the string ‘a’ or ‘UUID()’ casts to the double “0”. […]
请注意,此错误报告的范围并不严格限于在out上下文中隐式转换,并且这里提到的UUID()有点分心,因为UUID()可以返回以数字开头并转换为其他数字的字符串. ..但我认为它确实可以确认没有替代退出,因为除了“不要使用不同的类型进行比较,如果你想避免演员阵容”,我们已经知道,没有任何其他内容.它继续:
To avoid casting to
DOUBLE
internally ensure that the values compared are same datatype. In your case theid
columns are strings and the value you compare with should also be strings (not 1 but ‘1’ – not 2 but ‘2’ etc.) or usecast()
/convert()
in your statement […]
关于你的建议,如果要进行隐式转换,那么数字应该变成一个字符串而不是字符串变成一个数字…我可以看到你的观点,在某种程度上,对于严格的相等比较……但是有很多除了=并使用该逻辑之外的其他运算符,出现了一系列全新的问题……
mysql> SELECT CAST(100 AS CHAR) < '2';
+-------------------------+
| CAST(100 AS CHAR) < '2' |
+-------------------------+
| 1 |
+-------------------------+
1 row in set (0.00 sec)
正确!字符串’100’在字母意义上是“小于”字符串’2’…与字符串’AXX’相同的方式是“小于”字符串’B’.因此,这种替代方案肯定有其缺点.
然而,有第三种选择,它似乎是最准确的逻辑(虽然我欢迎建设性的反对意见):如果以非数字字符开头的字符串被强制转换为DOUBLE(或任何其他数字类型,为此但是,看起来这个演员的最正确的结果是NULL.
不幸的是,这不是MySQL方法.似乎这可以在源代码中修复,可能在sql / field.cc中,my_strntod()返回的’0’似乎只是在发生错误后抛出警告后返回给调用者,但尝试这样的黑客攻击源头深处超出了我的专长.
内容总结
以上是互联网集市为您收集整理的我可以配置MySQL的类型转换来考虑0!=’foo’吗?全部内容,希望文章能够帮你解决我可以配置MySQL的类型转换来考虑0!=’foo’吗?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。