漏洞=程序与生俱来的缺陷,安全漏洞=能被利用来越权的缺陷——教科书级的一类是缓冲区溢出:往装 10 格的盒子塞 11 份数据,多出来的那格正好覆盖返回地址,程序开始执行攻击者的代码。修漏洞的终极答案不是补丁,是写代码时就不给它出生。
本章终点站,也是全课的安全总收束:3-14 的内存布局(栈、返回地址)是溢出的作案现场;6-4 Cookie、6-10 SQL 注入、6-15 API 校验都是「缺陷→漏洞」的实例;6-16/6-17 的开源生态带来最后一节的供应链新战线。
一、三个词的层级
- Bug(缺陷):代码错,程序行为不对——算错金额也是它;
- 漏洞(Vulnerability):可被利用的缺陷——算错金额能被用来给自己加钱,就从 bug 升级为漏洞;
- 利用(Exploit):针对漏洞的攻击手法/代码;0day=厂商还不知道、无补丁可打的漏洞(最值钱)。
- 漏洞披露走 CVE 编号(如 CVE-2021-44228=Log4Shell)——全球统一的「病历号」;危险度按 CVSS 打分。
二、经典漏洞三大家族
① 内存破坏(C/C++ 的原罪)
- 缓冲区溢出:strcpy(buf, input) 不查长度——input 比 buf 大就漫过边界,栈上恰好摆着函数返回地址,多出来的字节把它改写→函数返回时跳到攻击者塞的代码;
- 现代 CPU 的地址空间随机化(ASLR)让地址猜不准、栈不可执行(NX)让塞进去的代码跑不起来、编译器加栈保护金丝雀——三件防弹衣把经典溢出打成残废,但内存安全缺陷至今仍是 CVE 大户(所以 Rust 兴起:编译期把内存错误变成编译错误)。
② Web 输入信任(6-4~6-10 的暗面) - SQL 注入:输入拼进 SQL(6-10 的红线)→ 参数化查询封死; - XSS:恶意脚本混进页面在别人浏览器里跑(偷 Cookie)→ 输出转义+HttpOnly; - CSRF:借你的登录态伪造请求 → Token 校验。 - 共同根因:把外部输入当自己人。
③ 认证与配置 弱密码、硬编码密钥、默认口令没改、越权访问(改 URL 里的 id 就看别人订单)——技术含量最低、事故占比最高的一类。
三、供应链:2020 年代的新战线
依赖(6-2)越多,攻击面越大——攻击者开始打「上游」:
- XZ Utils 后门(2024):攻击者潜伏维护者三年,把后门塞进压缩库——差点进入全球 Linux 的 SSH;
- Shai-Hulud 蠕虫(2025-09):npm 钓鱼偷维护者令牌、自我复制感染 500+ 包(含 chalk 等周下载 20 亿的包);
- axios 事件(2026-03):周下载 1 亿的库被抢注发毒版本。
- 防御:依赖锁定版本、开 MFA、审计(pip audit/npm audit)、SBOM(软件物料清单)。
动手 Demo:C 的溢出现场(Python 侧安全复刻)
# 概念演示:给「10 格的缓冲区」塞 16 字节,观察谁被踩了
buffer = bytearray(10) # 只能装 10 格
layout = {"[0:10] 缓冲区": buffer, "[10:18] 邻居(返回地址)": bytearray(b"OKRETURN")}
payload = b"A" * 10 + b"HACKED!!" # 10 格填满 + 8 字节漫出
print("攻击载荷:", payload.decode())
print("缓冲区内容:", bytes(buffer)) # AAAAAAAAAA —— 恰好满
print("邻居内容:", bytes(layout["[10:18] 邻居(返回地址)"])) # 还是 OKRETURN?
# 真实 C 语言里没有边界检查,漫出字节会真的写进邻居——
# 邻居若是返回地址,函数返回就跳去 HACKED! 的位置。
# Python 的 bytearray 越界会抛 IndexError:内存安全语言的防线在语言层。
try:
buffer[10] = ord("X")
except IndexError as e:
print("Python 拦下越界写入:", e)
看到什么算成功:打印载荷与布局后,Python 侧尝试 buffer[10] = "X" 被 IndexError 拦截——同一段逻辑在 C 里无人拦截(写坏内存继续跑),在 Python 里语言层就拒绝。
读结果:溢出的危害链=「越界写」+「邻居恰好是要害(返回地址/函数指针)」+「无任何检查」。三层防弹衣(ASLR/NX/金丝雀)与内存安全语言,分别在这条链的三环设卡。
30 秒实验
跑 open("user.txt", "w").write(input("名字: ")),输入 <script>alert(1)</script>——文件里现在躺着一段脚本。若这内容会被网页原样输出(不过滤),访问者浏览器就执行了它——XSS 的全部本质:输入是别人的,输出成什么样由你把关。安全 = 默认不信任一切输入。
常见误区
- 「漏洞都是黑客塞进来的」——绝大多数漏洞是开发者无心的缺陷;黑客只是利用者。XZ 事件那种潜伏是极少数。
- 「打上补丁就完事」——补丁只堵已知洞;修补周期内的窗口(披露到部署)才是最危险时段;「写安全的代码」优于「不停打补丁」。
- 「Python/Java 程序员不用懂内存溢出」——运行时挡住了越界写,挡不住逻辑漏洞(越权、注入);而且你以为的「安全」库底层是 C(OpenSSL Heartbleed 就是 C 层溢出,殃及所有上层语言)。
这本教材到此,全部完结。 🎉
六章链路(回头看一眼自己走过的路):
| 章 | 主题 | 留下的那一句话 |
|---|---|---|
| 1 | 编程的基础知识 | 编程=把想法翻译给机器,生态远比写代码大 |
| 2 | 编程语言都有什么不同 | 代码都要翻译成机器指令,语言只是翻译方式不同 |
| 3 | 数值和数据的处理方法 | 理想的数据处理方式=为数据选对结构 |
| 4 | 流程图与算法 | 有序思考=结构定骨架、算法定路径、复杂度定生死 |
| 5 | 从设计到测试 | 怎么写、怎么测、怎么管——可读、有测试、可交付 |
| 6 | Web技术与安全 | Web 是一层层借来的积木,安全是每一层的本分 |
三个【带得走的】东西(比任何一门语言都值钱):
- 【一切皆是翻译】的视角——源代码、编译器、字节码、字符编码、虚拟 DOM、反编译……整本书反复出现的就是【从人到机器的一层层翻译】,看懂翻译链就看懂了计算机;
- 先测量后说话的习惯——大 O 记账、覆盖率、静态指标、SPI/CPI 挣值……【感觉快】【感觉没问题】不算数,数字才作数;
- 默认不信任的习惯——输入是别人的(注入与 XSS)、依赖是别人的(供应链)、补丁是滞后的(少挖洞胜过勤打洞)——安全与质量都是设计出来的,不是补救出来的。
自测三问(点击展开)
1. **缓冲区溢出的危害链三环节?** 答:越界写入+邻居是要害(返回地址等)+无边界检查——堵住任一环即无害。 2. **SQL 注入与 XSS 的共同根因?** 答:把外部输入当可信数据直接拼进 SQL/HTML——防线分别是参数化查询与输出转义。 3. **供应链攻击打的是哪里?** 答:上游依赖——维护者账号、构建流水线、包仓库;防御靠锁定版本、MFA、依赖审计。- ☑ 6-19 完成 —— 从越界写到供应链:漏洞全景收官
- ☑ 第六章 完结 —— 教材这一章已读完十九节:从 HTML/HTTP 的骨架与搬运工(6-1)出发,经过库与框架(6-2)、CSS 与设计(6-3)、Cookie 与会话(6-4)、静态与动态(6-5)、MVC/MVVM(6-6)、DOM/Ajax(6-7)、jQuery 与虚拟 DOM(6-8)、四种数据格式(6-9)、SQL 与事务死锁(6-10/6-11)、VPS 与云计算(6-12/6-13)、虚拟机与容器(6-14)、API 与系统调用(6-15)、Git 与开源协议(6-16/6-17)、逆向工程(6-18),最后以漏洞全景收官(6-19)——Web 是一层层借来的积木,安全是每一层的本分
- ☑ 全书完结 —— 《完全图解编程原理》6 章已全部读完 🎉
相关笔记
- 指针与内存 —— 溢出的作案现场
- SQL —— 注入攻防的主战场
- Cookie —— XSS 偷的就是它
- 库 —— 供应链的依赖之桥
- ⌨️ 编程原理 · 索引 —— 全课路线图