安全 I · 系统与 Web 攻防
对标:Stanford CS155 / MIT 6.858 / OWASP Top 10 | 前置:csapp-01/04(内存)、web 线、db 线、crypto 线 安全课的教学立场很明确——理解攻击是为了构建防御。这一页按"漏洞类别 + 其防御"的方式,讲清最常见、最重要的几类安全问题(内存安全、注入、XSS、CSRF、认证缺陷),每类都是"机理 → 为什么危险 → 怎么防"。这是防御性的知识:一个不懂这些攻击面的开发者,会无意中写出满是漏洞的代码。核心心法一句话:永远不要信任来自外部的输入。
1. 安全的思维方式
普通开发问"怎么让它工作",安全思维问"怎么让它出错、边界在哪、攻击者能控制什么"。三条基本原则贯穿全页:
- 不信任输入:一切来自外部(用户、网络、文件)的数据都可能是恶意的——必须校验、净化、限制(web-02 边界校验的安全动机)。
- 最小权限:每个组件只给完成任务所需的最小权限——出事时爆炸半径小。
- 纵深防御:不指望单一防线,多层叠加(一层被破还有下一层)。
2. 内存安全漏洞(系统层)
C/C++ 的内存 bug(csapp-04)不只是崩溃,是安全漏洞——攻击者可利用它控制程序:
- 缓冲区溢出:写超出缓冲区边界(csapp-01 数组无边界检查)→ 覆盖相邻内存。若覆盖了栈上的返回地址(csapp-03 函数调用),攻击者可让程序跳到他控制的代码——控制流劫持。这是几十年来最经典的漏洞类。
- use-after-free / 二次释放:访问已释放内存(csapp-04)→ 可被操纵。
- 为什么至今仍是大问题:内存安全漏洞占业界严重漏洞约 70%。
防御(层层叠加):
- 语言层根治:用内存安全语言(Rust rust-01 的所有权、或带 GC 的语言 pl-02)——从源头消灭这一整类漏洞,这是本站语言线与安全线的关键呼应。
- 编译器/OS 缓解:栈保护(canary,检测返回地址被覆盖)、ASLR(地址随机化,让攻击者猜不到地址)、DEP/NX(数据页不可执行,防注入代码运行)——这些让利用变难,但不根治。
- 工具:AddressSanitizer/valgrind 开发期抓越界(csapp-04)。
- 纪律:边界检查、用安全的字符串/缓冲 API。
3. 注入攻击(Web 层最经典)
注入的通用机理:把用户输入当作代码/命令执行——当数据和代码的边界没守住时发生。
- SQL 注入:把用户输入直接拼进 SQL(db 线)→ 输入里的 SQL 片段被当查询执行,可绕过认证、读/改任意数据。根本原因是"用字符串拼接构造查询"。
- 防御(唯一正确解)——参数化查询 / 预编译语句:把 SQL 结构和数据分开传给数据库(
WHERE id = ?+ 单独传值),数据永远当数据、绝不当代码。ORM(web-02)默认用参数化,所以用好 ORM 天然防注入——但别用字符串拼接绕过它。永远不要用字符串拼接构造 SQL——这一条能防住绝大多数 SQL 注入。 - 命令注入 / 其他注入:把输入拼进 shell 命令、模板、LDAP 等同理——别把不可信输入拼进任何"会被解释执行"的字符串。用参数化 API、避免
shell=True拼接。
通用防御原则:数据与代码分离 + 输入校验(白名单优于黑名单)+ 输出编码。注入类漏洞的共同解药都是"别让数据越界变成代码"。
4. 浏览器端攻击:XSS 与 CSRF
Web 前端(web-03)的两类经典攻击,机理正好相反:
XSS(跨站脚本):攻击者让恶意脚本在受害者浏览器里执行——通常因为网站把用户输入未经转义地放进页面(如评论区存了 <script> 标签,别人看到就执行)。危害:偷 cookie/token(web-02 会话)、冒充用户操作。
- 防御:输出编码/转义(把用户内容当文本显示,不当 HTML/JS 解释——现代前端框架 React 默认转义,所以 web-03 的 React 天然抵御大部分 XSS,但
dangerouslySetInnerHTML会绕过要小心);内容安全策略(CSP)(限制页面能执行哪些脚本);cookie 设HttpOnly(JS 读不到,偷不走)。
CSRF(跨站请求伪造):攻击者诱导已登录用户的浏览器向目标网站发出非本意的请求(利用浏览器自动带 cookie)——如诱导你点一个链接,偷偷用你的登录态转账。
- 防御:CSRF token(表单带一个服务器验证的随机 token,第三方站点拿不到);cookie 设
SameSite(限制跨站带 cookie,现代浏览器默认,是最有效的缓解);对改状态的操作用 POST 而非 GET(web-01 方法语义)。
读法:XSS 是"恶意代码进了你的页面"、CSRF 是"你的登录态被别的站利用"——理解这对区别,才能正确选防御(转义 vs token)。两者都源于 Web 的信任模型漏洞。
5. 认证与访问控制缺陷
- 认证缺陷:弱密码存储(明文/弱哈希——crypto-01 要求加盐 + 慢哈希 bcrypt/argon2)、会话固定、token 泄露/不过期。
- 访问控制缺陷(授权):越权访问——改一下 URL 里的 id 就看到别人的数据(因为只认证了"你登录了",没检查"这条数据是不是你的")。这是 OWASP 排名第一的漏洞类,web-02 强调过"认证 ≠ 授权"正是防它。
- 防御:每个请求都在服务端检查"当前用户有权访问这个资源吗"(别信前端隐藏按钮就够——前端检查可绕过,授权必须在后端强制)。
6. 练习与要点
例 1(注入的边界思维) 看一段用字符串拼接构造 SQL 的代码,指出攻击者能怎么让输入越界成代码,然后改成参数化查询——理解"数据与代码分离"如何根治注入,不必真的去攻击任何系统,重点是学会识别这个反模式。
例 2(XSS vs CSRF 辨析) 给两个场景(评论区显示用户输入、一个自动提交的第三方表单),各判断是 XSS 还是 CSRF 风险、该用哪种防御——练"识别漏洞类别 → 选对防御"。
例 3(授权检查) 设计 Medusa 若加多用户后,"取某用户的数据"的端点该怎么在后端强制授权(不能只靠前端不显示)——把"认证 ≠ 授权、授权在后端"用到自己的系统设计。\(\blacksquare\)
下一页:安全 II——密钥、供应链与安全工程:把安全从"修漏洞"提升到"系统性的工程实践"——密钥管理、依赖供应链、以及安全左移。