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.模型前提 以单生产者对单消费者为例子: 前提一:有一个缓冲区作为消费场所。 前提二:有两种功能不同的线程分别具有消费与生产的能力。 前提三&…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
