Web安全攻防总览
1. 主要威胁分类
| 攻击 | 原理 | 防御 |
|---|---|---|
| XSS(跨站脚本) | 注入恶意 JS | 输出转义、CSP |
| CSRF(跨站请求伪造) | 利用登录态发请求 | SameSite cookie、token |
| SQL/NoSQL 注入 | 拼接 SQL | 参数化查询 |
| 点击劫持 | 透明 iframe | X-Frame-Options |
| SSRF | 服务端发恶意请求 | URL 白名单 |
| 目录遍历 | ../../ | 路径校验 |
| DDoS | 流量耗尽 | CDN/WAF/限流 |
| 暴力破解 | 撞密码 | 限速、验证码、MFA |
| 依赖漏洞 | 第三方库 CVE | 扫描、锁版本 |
2. XSS
2.1 三类
- 存储型:恶意脚本入库,所有访问者中招(评论、留言)
- 反射型:URL 参数带脚本,引诱点击
- DOM 型:JS 直接把 URL 含的内容塞 innerHTML
2.2 防御
// React / Vue 默认对 {} 内容做转义
<div>{userInput}</div> // 安全
// ✗ 绕过转义
<div dangerouslySetInnerHTML=}} __html: userInput }} />
<div v-html="userInput" />
// 必须用 v-html 时先净化
import DOMPurify from 'dompurify'
<div v-html="DOMPurify.sanitize(userInput)" />
服务端响应:
- 用模板引擎自动转义
- API 返回 JSON 而非 HTML
- 设 CSP
2.3 CSP(最强武器)
Content-Security-Policy: default-src 'self'; script-src 'self' 'sha256-xxx'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://api.example.com; frame-ancestors 'none'; base-uri 'self'
详见 CSP 与安全响应头一篇。
3. CSRF
3.1 原理
用户登录 a.com 后访问 b.com(恶意网站),b.com 让浏览器向 a.com 发请求(带 cookie)→ 后端以为是用户操作。
3.2 防御
# Cookie 必须设
Set-Cookie: session=abc; HttpOnly; Secure; SameSite=Strict
SameSite:
Strict:完全不跟随跨站Lax:跨站 GET 跟随(默认)None:必须配 Secure
加 CSRF token:
<form>
<input type="hidden" name="_csrf" value="abc123" />
</form>
后端验证 token 与 session 绑定。
API 用 SPA / token 头(非 cookie)就基本不存在 CSRF(attacker 拿不到 token)。
4. 点击劫持
恶意网站把目标网站套 iframe,覆盖透明按钮诱骗点击。
X-Frame-Options: SAMEORIGIN # 老语法
# 或 CSP(新)
Content-Security-Policy: frame-ancestors 'self'
5. SSRF
服务端代理用户输入的 URL 时被恶意构造请求内网:
http://api.example.com/proxy?url=http://169.254.169.254/ # AWS metadata
http://api.example.com/proxy?url=http://localhost:6379/ # 内网 Redis
防御:
- URL 白名单(只允许特定域)
- DNS 解析后判断 IP(不在私网段)
- 禁止
file://gopher://等危险 scheme
6. CORS 配置陷阱
# ✗ 危险
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true # 一起用就是反射所有 origin
# ✓ 白名单 + Vary
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
Vary: Origin
后端按 Origin 白名单判断,动态返回。* + credentials 浏览器也会拒绝,但有些后端框架默认允许,是常见错误。
7. 文件上传
危险点:
- 上传
.php/.jsp直接执行 - 上传 SVG 含
<script> - 上传巨大文件 DoS
- 上传 ZIP 解压炸弹
防御:
- 白名单后缀(不是黑名单)
- 强制重命名(hash + ext)
- 上传到不可执行目录 / 对象存储
- 限大小
- SVG 走 sanitize 或转 PNG
8. 认证与会话
8.1 密码
- bcrypt / argon2,never MD5/SHA1
- 限制错误次数 + 验证码
- 密码强度
8.2 Session / JWT
- Session:服务端存(Redis),cookie 只存 ID
- JWT:无状态,但难撤销,泄露后果重
- HttpOnly + Secure + SameSite
8.3 MFA
支持 TOTP(Google Authenticator)/ WebAuthn / 硬件 key。
9. 速率限制
防爆破、防爬、防 DoS:
- 登录接口:5 次 / 分钟 / IP + 账号
- 注册:1 次 / 分钟 / IP
- 短信验证码:1 次 / 60 秒 / 手机号
- 全局:100 req / 秒 / IP
详见模块 03 Nginx 限流。
10. 日志与审计
- 登录、改密、敏感操作必记日志
- 含 IP、UA、时间、操作详情
- 日志不能含密码 / 完整 token
- 7 天 - 1 年保留(按合规)
11. 安全响应头集合
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Content-Security-Policy: default-src 'self'; ...
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin
12. 上线前 checklist
- 全站 HTTPS + HSTS
- 安全响应头齐全(A 级以上)
- 依赖扫描无高危
- 镜像扫描无高危
- CSP 不含 unsafe-eval / unsafe-inline(除非必须)
- cookie SameSite + Secure + HttpOnly
- CORS 白名单
- 限流配置
- 日志脱敏
- 备份策略
- 应急预案
13. 常见反模式
- DOM 直塞用户输入:XSS
Allow-Origin: *+ credentials:等于反射任意 Origin- cookie 不设 HttpOnly:JS 能读,XSS 一发就泄
- JWT secret 弱 / 写代码:伪造 token
- 错误信息含堆栈 / SQL:信息泄露
- 生产关 CSP 调试:忘记开
- 依赖几年不更新:CVE 累积
- 管理后台和业务同域:XSS 一处通杀
14. 延伸阅读
- OWASP Top 10
- MDN: Web Security
- securityheaders.com
- 《白帽子讲 Web 安全》吴翰清
- 模块 10 各专题文档