MySQL一隐式转换
我相信90%以上的同学们在平时开发时,或多或少都被隐式转换(CONVERT_IMPLICIT)坑过,甚至测出bug前你都浑然不知。你还别不信,“无形之刃,最为致命!”
mysql> SELECT * from t_user;
+----+-----------+----------+
| id | username | password |
+----+-----------+----------+
| 1 | 陈哈哈 | abcd1234 |
| 2 | 侨布斯 | 1234 |
| 3 | 提莫 | 1234abcd |
+----+-----------+----------+
3 rows in set (0.00 sec)
不能展示真实数据,见谅~~ 上面是这张用户表的原始数据,侨总用下面的SQL查询自己这行数据,大家先看看有没有问题?
SELECT * from t_user where `password`=1234;
mysql> SELECT * from t_user where `password`=1234;
+----+-----------+----------+
| id | username | password |
+----+-----------+----------+
| 2 | 侨布斯 | 1234 |
| 3 | 提莫 | 1234abcd |
+----+-----------+----------+
2 rows in set, 1 warning (0.00 sec)
???这怎么把提莫队长给打现行了?
好了,其实这算是MySQL给开发者留下的不友好的礼物(坑)。今天我们一起从以下三个角度去聊一聊MySQL的隐式转换。
1、SQL语句中隐式转换的坑
先看一下官方的隐试转换说明:
翻译成人话:
- 两个参数至少有一个是 NULL 时,比较的结果也是 NULL,例外是使用 <=> 对两个 NULL 做比较时会返回 1,这两种情况都不需要做类型转换。
- 两个参数都是字符串,会按照字符串来比较,不做类型转换
- 两个参数都是整数,按照整数来比较,不做类型转换
- 十六进制的值和非数字做比较时,会被当做二进制串
- 有一个参数是 TIMESTAMP 或 DATETIME,并且另外一个参数是常量,常量会被转换为 timestamp
- 有一个参数是 decimal 类型,如果另外一个参数是 decimal 或者整数,会将整数转换为 decimal 后进行比较,如果另外一个参数是浮点数,则会把 decimal 转换为浮点数进行比较
所有其他情况下,两个参数都会被转换为浮点数再进行比较
。(这里所说的浮点数一般默认为double类型)
可以看到,非前六种以外的类型转换都要转成浮点类型来处理,这意味着什么?意味着MySQL承认了隐式转换这个事儿,还表示不爱看官方文档的哥们儿出问题活该~~
我们用一些具体示例来看一下,通过下述SQL可见,当1234没有引号也就是整数时,‘1234abcd’ = 1234 → true,说明MySQL对’1234abcd’做了转型,转成了浮点类型,结果是:1234abcd => 1234
# 0:false;1:true
mysql> SELECT '1234abcd' = '1234';
+---------------------+
| '1234abcd' = '1234' |
+---------------------+
| 0 |
+---------------------+
1 row in set (0.00 sec)# 0:false;1:true
mysql> SELECT '1234abcd' = 1234;
+-------------------+
| '1234abcd' = 1234 |
+-------------------+
| 1 |
+-------------------+
1 row in set, 1 warning (0.00 sec)
为啥1234abcd => 1234呢? 其实’1234’和’abcd’都会转成浮点数,即:1234+0=1234
,非数字类型的都被直接转成了 0
mysql> SELECT '1234' + 'abcd';
+-----------------+
| '1234' + 'abcd' |
+-----------------+
| 1234 |
+-----------------+
1 row in set, 1 warning (0.00 sec)
你发现了什么?原来字符串涉及到 +
、=
、-
、/
等等运算符时都会进行隐式转型,也就是转成double
,那么字符串转double是怎么转的呢?
# 转成:'1aaaa' = 1
mysql> SELECT '1aaaa' = 1;
+-------------+
| '1aaaa' = 1 |
+-------------+
| 1 |
+-------------+
1 row in set, 1 warning (0.00 sec)# 转成:'a1111' = 0
mysql> SELECT 'a1111' = 1;
+-------------+
| 'a1111' = 1 |
+-------------+
| 0 |
+-------------+
1 row in set, 1 warning (0.00 sec)# 转成:0 + 0 =0
mysql> SELECT 'aa' + 'aa' = 1;
+-----------------+
| 'aa' + 'aa' = 1 |
+-----------------+
| 0 |
+-----------------+
1 row in set, 2 warnings (0.00 sec)# 转成:0 + 0 + 1 =1
mysql> SELECT 'aa' + 'aa' + '1' = 1;
+-----------------------+
| 'aa' + 'aa' + '1' = 1 |
+-----------------------+
| 1 |
+-----------------------+
1 row in set, 2 warnings (0.00 sec)
可见,是以字符串从左向右取值的,且从非数字起后面的值都被转成 0
,如a11111
,第一位为a
,则整体转为 0
;1aaaa
第一位为1
,第二位为a
,从第二位往后转成0
,得a11111
→ 0
mysql> SELECT * from t_user where `password`=1234;
+----+-----------+----------+
| id | username | password |
+----+-----------+----------+
| 2 | 侨布斯 | 1234 |
| 3 | 提莫 | 1234abcd |
+----+-----------+----------+
2 rows in set, 1 warning (0.00 sec)
现在我们就明白为什么能匹配到提莫
了。因为在不同类型转换时"1234abcd"被转成了浮点类型,"abcd"转成浮点型后为0
,因此MySQL判为:“1234abcd” = ‘1234’ + 0 。
2、黑客同学喜欢用隐式转换进行SQL注入攻击
通过第一部分隐式转换的了解,我们可以预测一些简单SQL注入的方式:
mysql> SELECT * from t_user where username='陈哈哈' and `password`=0;
+----+-----------+----------+
| id | username | password |
+----+-----------+----------+
| 1 | 陈哈哈 | abcd1234 |
+----+-----------+----------+
1 row in set, 1 warning (0.00 sec)
如果有些朋友公司的网站用的是下面的写法:
select * from t_user where username=${username} and `password`=${password};
不然有些小伙伴友好的把请求参数构建成 username → a' OR 1='1
,那么password是啥都无所谓了,是吧。
懂我意思吧,快改了。
当然,其实很多注入攻击的真实目的,并不是用来破解用户账号的,而是破坏服务器。一般我们在页面F12发现有问题的接口后,通过脚本模拟请求参数(构造注入参数),去不断尝试自定义构造limit、order、where等条件,或许花不了多久就能通过一个不规范的请求入口,检索出该表甚至其他大表全量信息。导致公司服务器负载异常,连接数打满,CPU200%等有趣的情况。有兴趣的同学可以花几小时尝试破解自己公司的web~~
3、索引中隐式转换的坑
同理,在MySQL根据索引进行查询时,如果你的username字段有索引且为varchar类型,且查询如下时:
select * from t_user where username=123;
该SQL会出现两个问题:
1、索引失效
无法使用到索引查询,因为mysql会在引擎层进行类型隐式转换(CONVERT_IMPLICIT),会先把username隐式转换成浮点数,然后再跟你的123
进行比较,然而你的索引是建在username上的,并不是在转换后的username上的,所以进行转换后的username相当于没有索引。会全表扫描,换做大表中,无法使用索引,你懂得。
2、查询结果不准确
第一部分我们已经举例说明,MySQL在隐式转换时的varchar转double,会出现很多意想不到的情况,比如 “123”," 123","123a"都会转成123,实际场景中都是不允许出现的。
总结
就是当sql中一个字符串和一个数字做+
、=
、-
、/
计算时,如"a1bc"+1, "ccccd3"=0
这个字符串中的非数字的字符会被隐式转换成0并且再转换为空,再去做比较.只分以下两种情况:
1.前面的字符不是数字时,直接等于0,如"a1"=0,"abcd1"=0
2.前面的字符是数字时,从第一个开始截取,从左往右直到出现的第一个不是数字的字符为止,截取的字符串就是最终转换的值,如"1a"=1,"2a3b"=2,"55555h666666"=55555
相关文章:

MySQL一隐式转换
我相信90%以上的同学们在平时开发时,或多或少都被隐式转换(CONVERT_IMPLICIT)坑过,甚至测出bug前你都浑然不知。你还别不信,“无形之刃,最为致命!” mysql> SELECT * from t_user; ---------…...

风光并网对电网电能质量影响的matlab/simulink仿真建模
之前配电网的一个项目,我把其中一部分分享给大家,电能质量影响这部分,我在模型中主要体现的就是不同容量的光伏、风电接入,对并网点的电压影响情况。(主页还有单独风电并网系统,光伏并网发电系统以及微电网…...

浅谈Spring循环依赖
文章目录1.前言2.什么是循环依赖?3.两种Spring容器循环依赖3.1.构造器循环依赖(无法解决)3.2.setter循环依赖(可以解决)3.3.小结4.循环依赖检查5.循环依赖的处理5.1.单例setter循环依赖5.2.Spring解决循环依赖5.3. 循环…...
华为OD机试题 - 拼接 URL(JavaScript)| 包含代码编写思路
最近更新的博客 华为OD机试题 - 字符串加密(JavaScript) 华为OD机试题 - 字母消消乐(JavaScript) 华为OD机试题 - 字母计数(JavaScript) 华为OD机试题 - 整数分解(JavaScript) 华为OD机试题 - 单词反转(JavaScript) 华为OD机试题 最近更新的博客使用说明拼接 URL题目…...
【FFMPEG】Filtering Introduction[翻译/举例]
Filtering Introduction Filtering in FFmpeg is enabled through the libavfilter library. FFmpeg中的Filtering可以通过libavfilter library来使用。 In libavfilter, a filter can have multiple inputs and multiple outputs. To illustrate the sorts of things that are…...

什么是IP65?仅仅是防水等级吗?看完本文直呼666!
IP65在硬件设备,准确的来说在电气设备中,这个参数很常见,但是作为网络技术的博主,为啥要介绍IP65? 这个很好解释,因为网络设备,比如路由器、交换机,还有服务器、监控等都是属于电气…...
Flask入门(10):数据库连接池
目录10.数据库连接池模式一模式二示例:使用数据库连接池进行登录验证10.数据库连接池 参考:https://www.cnblogs.com/wangkun122/articles/8992637.html 通过DBUtils实现数据库连接池 安装: pip install DBUtils1.2注意:pytho…...

华为OD机试C++实现 - 最小步骤数
最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…...
数仓:用户行为类指标一网打尽
前言 用户行为分析是对用户在产品或触点上产生的行为及行为背后的数据进行分析,通过构建用户行为数据分析体系或者用户画像,来改变产品、营销、运营决策,实现精细化运营,指导业务增长。总之,很重要。 先来看下用户类…...
mysql数据库的主从复制
一、实现主从复制的方式。 异步复制:它是mysql默认的同步方式,从库通过io线程去拉取 bin log时,主库不需要关注这个时候是否有从库在同步数据,他只做自己的事情就可以了, 整个复制过程都是异步完成的 ; 半同步复制&…...

【极海APM32替代笔记】低功耗模式、WFI命令等进入不了休眠的可能原因(系统定时器SysTick一直产生中断)
【极海APM32替代笔记】低功耗模式、WFI命令等进入不了休眠的可能原因(系统定时器SysTick一直产生中断) 【STM32笔记】低功耗模式配置及避坑汇总 前文: blog.csdn.net/weixin_53403301/article/details/128216064 【STM32笔记】HAL库低功耗模…...

一文搞懂秒杀系统,欢迎参与开源,提交PR,提高竞争力。早日上岸,升职加薪。
前言 秒杀和高并发是面试的高频考点,也是我们做电商项目必知必会的场景。欢迎大家参与我们的开源项目,提交PR,提高竞争力。早日上岸,升职加薪。 知识点详解 秒杀系统架构图 秒杀流程图 秒杀系统设计 这篇文章一万多字,…...

华为OD机试真题 用 C++ 实现 - 子序列长度 | 多看题,提高通过率
最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…...
华为OD机试题 - 符合条件的子串长度(JavaScript)| 包含代码编写思路
最近更新的博客 华为OD机试题 - 字符串加密(JavaScript) 华为OD机试题 - 字母消消乐(JavaScript) 华为OD机试题 - 字母计数(JavaScript) 华为OD机试题 - 整数分解(JavaScript) 华为OD机试题 - 单词反转(JavaScript) 华为OD机试题 最近更新的博客使用说明符合条件的子…...

快速读懂网络拓扑图
快速读懂网络拓扑图几重常见的网络拓扑总线型拓扑简介优点缺点环型拓扑简介优点缺点星型拓扑简介优点缺点网络层级机构节点结点链路通路不同的连接线代表什么意思?不同颜色、粗细的直线代表什么意思?闪电线-串行链路几重常见的网络拓扑 总线型拓扑 简介…...
《上海市创新型企业总部认定和奖励管理办法》
各区人民政府、有关单位: 为加快推动上海创新型经济发展,支持各类高成长性企业和研发机构升级打造创新型企业总部,培育壮大更多高能级创新主体,为建设具有全球影响力的科技创新中心提供支撑,现将《上海市创新型企业总…...

LeetCode 160. 相交链表 -- 消除长度差
相交链表 简单 2K 相关企业 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 图示两个链表在节点 c1 开始相交: 题目数据 保证 整个链式结构中不存在环。 注意…...

《分布式技术原理与算法解析》学习笔记Day19
分布式通信:消息队列 什么是消息队列? 队列是一种具有先进先出特点的数据结构,消息队列是基于队列实现的、存储具有特定格式的消息数据。消息以特定格式放入这个队列的尾部后直接返回,不需要系统马上处理,之后有其他…...

云、安全、网络三位一体,Akamai 推出大规模分布式边缘和云平台 Akamai Connected Cloud
出品 | CSDN 云计算 云服务市场规模在持续增长。 基于网络技术积累与优势,与布局边缘计算之后,巨头 Akamai 在继续推进它的技术与产品进程。近日,Akamai 正式推出大规模分布式边缘和云平台 Akamai Connected Cloud,包含云计算、安…...

生产者消费者模型(多线程工作)
目录 1.模型前提 2.阻塞队列(消费场所) 3. 实验 4.有关效率 1.模型前提 以单生产者对单消费者为例子: 前提一:有一个缓冲区作为消费场所。 前提二:有两种功能不同的线程分别具有消费与生产的能力。 前提三&…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...