本章跟着一条线走:攻击者想要的共同效果是让“用户输入”被系统错当成“可执行代码”——SQL 注入把输入塞进查询语句,XSS 把脚本塞进别人的浏览器,CSRF 借用户自己的会话发指令。三节课打的是同一种信任错位。
第一幕给了攻击面:第二幕点燃第一把火。这一章的三个漏洞共享一个根因——系统分不清“数据”和“代码”。SQL 注入在于后端把输入拼进查询;XSS 在于浏览器把输入当成了页面脚本;CSRF 在于服务器把“来自自己浏览器的请求”默认成“用户自愿的动作”。看懂这层错位,比背载荷值钱。
用一个贯穿问题串起本章:为什么看似合法的输入,一旦被放进不同的“解析上下文”,就会变成武器?沿着三个站点推进——先看 SQL 注入怎么篡改查询语义,再看 XSS 怎么借浏览器执行脚本,最后看 CSRF 怎么让服务器误信一个本来无辜的请求。
下图把三个漏洞画成同根的三条支流:共同源都是“不可信数据越过边界”,只是各自落进了不同的解析器。
三站的共同出口是一致的:只要你能想出“把输入塞进解析器”的办法,攻击就可能成立;把数据与代码分离,是这一整章永远成立的药方。
这一幕真正的认知拐点:安全边界不是写在代码行数里的,而是写在“解析上下文”里的——同一个字符,在字符串常量里无害,在查询语句里能改逻辑,在 HTML 标签里能触发脚本。意识到“上下文特异化”,你就能一次性防住一整个家族的注入,而不是逐条堵已知载荷。
另一个落点:这三类漏洞的缓解大多不在“防特定关键词”,而在机制层(参数化、编码、令牌校验)。理解了为什么机制有效,你才会真正信任它,而不是过几天又退回字符串拼接的老路。这套“机制优先”的思路也会一路贯穿到第五幕的加固工具箱:能靠框架默认能力解决的,就不要靠人手逐条补丁。
再补一个有现实意义的观察:注入家族里最容易回潮的不是最尖的技术,而是最基础的拼接与回显。很多团队在热修复时临时手拼了一段 SQL、或图省事把错误信息原样回显,几周后就变成新的漏洞点。所以真正管住这一章的不是“一次性改对”,而是把“参数化、输出编码、令牌校验”变成分支合并的强制检查项,让回潮在代码评审阶段就被拦下来。
第二幕解决的是“输入变成代码”的攻击;下一幕换一个战场,攻击者绕过输入层,直接在“你是谁、你能看什么”上做文章,也就是认证、会话与访问控制失守。资产仍然一样,但破口从解析器挪到了身份与授权逻辑。