对于SQL注入原理的学习
0x00 前言
写下本文的直接原因是拜读了庆尘大佬的文章(对SQL注入漏洞原理的思考 (qq.com),这也是本文的参考文章。推荐大家读读大佬的文章,感受大佬浅显易懂的文笔下的深邃思想。
0x01 信任输入
信任问题
安全问题的本质就是信任问题
例如对一个网站的开发来说
- 信任普通用户的输入——前台漏洞
- 信任管理员用户的输入——后台漏洞
- 信任离线升级/在线升级/自动化升级/升级包——供应链攻击
- 不信任任何输入——信任代码逻辑——逻辑漏洞
有时候信任是可以被提升的——越权。
防御核心
对应的安全方案有很多,但都可以简化为
输入——检测是否存在风险——输出
黑客往往是从输入入手。所以我们重点关心的问题也就是如何处理信任与输入的关系
0x02 控制流和数据流
可以将程序员的代码分割为两个部分
- 一部分是控制代码走向的控制流代码
- 另一部分是用来被展示,被存储,被流转的数据流(包括输入的数据和程序员设定的数据)
被,是被动,说明了数据流的数据不应该具有主动性。说实在一点,外来的数据不能影响内部的控制程序。一旦数据流可以入侵到控制流,那么漏洞也随之而生。
0x03 以SQL注入为例
薄弱的程序
先看一段简单的代码:
1 |
|
这是一个最简单的SQL注入代码,再看看payload:
1 | username=admin' and 1=1 # |
让我们理理逻辑:
1 | 输入——php字符变量——SQL语句——数据库 |
很好,这就搭建起了输入和后端的关系。
背后的原理
程序员希望我们输入的是正常的数据,也就是程序员期望得到一个不能影响控制流的输入流。
但是我们的payload通过绕过闭合,成功使数据流入侵了控制流。
正如上文所说:
一旦数据流可以入侵到控制流,那么漏洞也随之而生。
- 这里就引出了代码审计的两个核心
- 能否让数据流逃逸到控制流
- 业务逻辑可能产生的点在哪
0x04 预编译
以PHP的预编译为例:
1 | // 创建连接 |
预编译为什么能防止SQL注入
预编译语句通过将SQL查询语句与参数分开,使用占位符来代表参数,然后将用户输入的数据绑定到占位符上,确保了输入数据被正确地解释为字符串而不是SQL代码。因此,无论用户输入什么数据,都不会影响原始查询的结构和意图,从而有效地防止了SQL注入攻击。
让我们再理理思路:
- 为什么需要使用预编译——因为要防止SQL注入
- 为什么要防止SQL注入——防止数据流入侵到控制流
- 怎样防止数据流入侵到控制流——将用户的输入限制到输入流
归根结底,还是要限制用户的输入,也就是回到了信任的问题上
0x05 结语
我写的这篇文章抄袭居多,思路生硬,但是仍然写出来,是因为学习安全需要对问题本质上的思考,哲学上的思考。不写,不得深思。
另外,我也很希望读到能上升到思想与哲学的文章,再次感谢庆尘大佬。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 山 · 水!
评论