⌨️ 第六章 Web技术与安全
📄 本篇一句话

漏洞=程序与生俱来的缺陷,安全漏洞=能被利用来越权的缺陷——教科书级的一类是缓冲区溢出:往装 10 格的盒子塞 11 份数据,多出来的那格正好覆盖返回地址,程序开始执行攻击者的代码。修漏洞的终极答案不是补丁,是写代码时就不给它出生。

📝 在本章的位置

本章终点站,也是全课的安全总收束:3-14 的内存布局(栈、返回地址)是溢出的作案现场;6-4 Cookie、6-10 SQL 注入、6-15 API 校验都是「缺陷→漏洞」的实例;6-16/6-17 的开源生态带来最后一节的供应链新战线。

一、三个词的层级

二、经典漏洞三大家族

① 内存破坏(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 的全部本质:输入是别人的,输出成什么样由你把关。安全 = 默认不信任一切输入。

常见误区


这本教材到此,全部完结。 🎉

六章链路(回头看一眼自己走过的路):

章 主题 留下的那一句话
1 编程的基础知识 编程=把想法翻译给机器,生态远比写代码大
2 编程语言都有什么不同 代码都要翻译成机器指令,语言只是翻译方式不同
3 数值和数据的处理方法 理想的数据处理方式=为数据选对结构
4 流程图与算法 有序思考=结构定骨架、算法定路径、复杂度定生死
5 从设计到测试 怎么写、怎么测、怎么管——可读、有测试、可交付
6 Web技术与安全 Web 是一层层借来的积木,安全是每一层的本分

三个【带得走的】东西(比任何一门语言都值钱):

  1. 【一切皆是翻译】的视角——源代码、编译器、字节码、字符编码、虚拟 DOM、反编译……整本书反复出现的就是【从人到机器的一层层翻译】,看懂翻译链就看懂了计算机;
  2. 先测量后说话的习惯——大 O 记账、覆盖率、静态指标、SPI/CPI 挣值……【感觉快】【感觉没问题】不算数,数字才作数;
  3. 默认不信任的习惯——输入是别人的(注入与 XSS)、依赖是别人的(供应链)、补丁是滞后的(少挖洞胜过勤打洞)——安全与质量都是设计出来的,不是补救出来的。
自测三问(点击展开) 1. **缓冲区溢出的危害链三环节?** 答:越界写入+邻居是要害(返回地址等)+无边界检查——堵住任一环即无害。 2. **SQL 注入与 XSS 的共同根因?** 答:把外部输入当可信数据直接拼进 SQL/HTML——防线分别是参数化查询与输出转义。 3. **供应链攻击打的是哪里?** 答:上游依赖——维护者账号、构建流水线、包仓库;防御靠锁定版本、MFA、依赖审计。

相关笔记