前面刚弄明白:
- 数据库是什么
- SELECT 查询
- WHERE 条件
- ORDER BY 排序
- LIMIT 分页
本来以为已经差不多了,结果发现无论看什么 SQL 注入教程。
总会出现一个熟悉的东西:UNION
刚开始看到它的时候,我完全不知道它是干什么的,直到真正学习之后才发现,很多 SQL 注入知识,其实都是围绕 UNION 展开的。
今天就结合自己的学习过程,聊聊我最近对 UNION 的理解。
一、UNION 到底是什么?
先不要把它想得太复杂,我现在对 UNION 最简单的理解是:把多个查询结果合并到一起
例如有两张表。
第一张表:
| id | username |
| 1 | admin |
| 2 | test |
第二张表:
| id | username |
| 1 | user |
| 2 | guest |
如果分别查询: SELECT username FROM table_a;
得到:
admin
test
再查询: SELECT username FROM table_b;
得到:
user
guest
而 UNION 的作用就是:
SELECT username FROM table_aUNIONSELECT username FROM table_b;
结果:
admin
test
user
guest
看到这里的时候。
我突然觉得:UNION 有点像拼接数据把两次查询的结果放到一起展示。
二、为什么数据库要设计 UNION?
我一直有个疑问:既然能查一次为什么还要合并查询?
后来发现,现实开发中非常常见。
例如,网站有:
- 普通用户表
- 管理员表
有时候开发需要把两个结果一起显示。
这时候就会用到:UNION
所以它本来就是数据库提供的正常功能,并不是专门为了安全研究设计的。
三、UNION 最重要的规则
学习 UNION 时,我发现一个知识点特别重要。
那就是:字段数量必须一致
例如:
正确:
SELECT id,username UNION SELECT id,nickname;
两个查询都是两列 所以能够合并。
如果这样:
SELECTid,usernameUNION SELECTnickname;
就会出错。
因为:
前面两列
后面一列
数量对不上,数据库不知道怎么拼接。
四、我终于明白为什么总有人研究字段数
以前看 SQL 注入文章经常看到:判断字段数当时特别困惑。
为什么这么执着于字段数量?
后来学 UNION 才明白。
因为:UNION 合并查询 必须保证字段数量一致
如果数量不一致,数据库直接报错。
所以很多人研究字段数,本质上是在研究:
原来的查询到底返回几列 这样后面才能正确组合查询结果。
五、UNION 和 ORDER BY 的关系
我又想起上一篇学习的: ORDER BY
后来发现,很多 SQL 注入学习路线里。
ORDER BY 经常出现在 UNION 前面。
原因其实很简单。
因为:ORDER BY能够帮助我们了解:查询结构有多少列
而:UNION 又要求字段数一致。
这样两者就串起来了。
以前觉得这些知识点毫无关联。
现在慢慢开始连接起来。
六、我开始发现 SQL 学习越来越有意思
刚开始学数据库的时候。感觉全是命令,特别枯燥。
后来发现,其实很多命令背后都有自己的逻辑。
例如:
- WHERE 负责筛选
- ORDER BY 负责排序
- LIMIT 负责分页
- UNION 负责合并结果
这样理解之后,SQL 好像突然变得简单了很多。
七、为什么不要急着背各种注入技巧
最近学习过程中,我越来越有一个感受,很多人一开始学 SQL 注入。
最想看的往往是:
- 报错注入
- 联合查询
- 盲注
- 各种技巧
但如果不知道:UNION 为什么存在
那么后面的内容基本都会变成:死记硬背
而真正理解 UNION 后,你会发现:很多知识其实是在利用数据库本身的特性。
八、我现在对 SQL 注入的理解
以前我觉得:
SQL注入=各种神秘技巧
现在越来越觉得:
SQL注入=理解数据库+理解SQL+理解用户输入
数据库本身没有问题,SQL 语句本身也没有问题。
真正的问题在于:用户输入影响了数据库原本想执行的逻辑
而 UNION。
正是理解这个过程的重要一环。
九、最后
以前我看到 UNION,只觉得它是一个陌生的 SQL 命令。
真正学习之后才发现,它其实只是数据库用来:合并查询结果的一种正常功能。
而对于学习 SQL 注入的人来说,理解 UNION 的意义。
并不是为了记住一个命令。
而是为了开始真正理解:数据库是如何处理查询的