前端安全深度话题
XSS · CSRF · CSP · 越权 IDOR · token 存储 — 区分会写和专业
🎬 怎么引出
「安全这块我有实战意识 — 做 LLM 对话时,模型输出我一定用 DOMPurify 清洗后才 v-html,因为模型可能产生恶意脚本;富文本编辑器粘贴 Word 内容,白名单过滤防 XSS;多租户系统我强调前端隔离只是体验,数据安全命门在后端校验。」安全是高级前端的标志,讲深能拉开档次。
1
XSS(跨站脚本攻击)
| 类型 | 怎么注入 | 危害 |
|---|---|---|
| 存储型 | 恶意脚本存数据库,别人访问执行 | 最严重(评论/留言) |
| 反射型 | URL 参数带脚本,服务端原样返回 | 需诱导点击 |
| DOM 型 | 纯前端,JS 操作 DOM 注入 | 不经过服务端 |
危害: 偷 cookie/token、劫持会话、篡改页面、键盘记录、挖矿、蠕虫传播。XSS 是前端第一安全威胁。
🛡️ 防御
- 输出转义: 用户内容渲染前转义 < > & " '(Vue 的 {{}} 默认转义,v-html 才危险)
- DOMPurify: 必须渲染 HTML 时(富文本/LLM),用 DOMPurify.sanitize() 清洗
- CSP: Content-Security-Policy 限制脚本来源(下节详述)
- HttpOnly Cookie: token 存 HttpOnly cookie,JS 读不到,XSS 偷不走
- 不要拼字符串生成 HTML: 用 textContent / createElement,不用 innerHTML 拼接
⚠️ 高危场景:v-html
Vue 的 v-html 和 React 的 dangerouslySetInnerHTML 是 XSS 重灾区。 任何用户可控的内容(评论、富文本、LLM 输出、URL 参数)直接 v-html = 招呼攻击者来。必须 DOMPurify 清洗。Vue 模板 {{}} 是安全的(自动转义),只有 v-html 危险。
2
CSRF(跨站请求伪造)
🧠 原理
你登录了银行(A),又访问了恶意网站(B)。B 里有个表单/图片发请求到 A 转账。浏览器会自动带上 A 的 cookie(同源策略不拦截发请求,只拦读响应),于是转账成功。CSRF = 借你的 cookie 冒充你。
和 XSS 区别: XSS 是注入脚本执行(在你网站内);CSRF 是冒充你发请求(从别的网站)。XSS 防御靠转义/清洗;CSRF 防御靠 token / SameSite。
🛡️ 防御
- CSRF Token: 服务端发一次性 token,表单带上,校验(攻击者拿不到)
- SameSite Cookie: SameSite=Lax/Strict,跨站不带 cookie(现代浏览器默认 Lax)
- Referer/Origin 校验: 服务端检查请求来源
- 关键操作二次验证: 转账/改密码要短信/验证码
3
CSP(内容安全策略)
CSP 是什么: 通过 HTTP 头或 meta 标签,告诉浏览器只允许从哪些来源加载脚本/样式/图片。即使有 XSS,恶意脚本(来自非白名单域)也无法执行。是 XSS 的最后一道防线。
📋 CSP 配置示例
<!-- HTTP 头或 meta -->
Content-Security-Policy:
default-src 'self'; # 默认只允许同源
script-src 'self' cdn.example.com; # 脚本只允许同源 + 指定 CDN
style-src 'self' 'unsafe-inline'; # 样式允许 inline
img-src 'self' data: https:; # 图片允许 data 和 https
connect-api 'self'; # AJAX 只允许同源
# 关键:禁止 inline script 和 eval,堵死大部分 XSS
坑: CSP 上线前先用
Content-Security-Policy-Report-Only(只上报不拦截)观察一段时间,避免误伤正常功能(很多老项目大量 inline script)。
4
越权漏洞(IDOR)
⚠️ 经典越权
现象: 用户 A 登录后,直接改 URL 的 /api/order/123 为 /api/order/456(B 的订单),竟然能看/改 B 的数据。这就是水平越权(IDOR,不安全的直接对象引用)。
根因: 后端只校验"登录了没",没校验"这个资源是不是你的"。防御: 每个接口校验资源归属,基于当前用户的 tenantId/userId 过滤。前端菜单隐藏没用,要后端校验。
垂直越权: 普通用户能调管理员接口(如
/api/admin/deleteUser)。防御: 后端每个接口校验角色权限,不只前端隐藏按钮。
5
token 存哪(localStorage vs Cookie)
localStorage
- ✅ JS 可读,灵活(能自定义 header)
- ❌ JS 可读 = 易受 XSS
- ❌ 不自动带请求
- 适合:SPA,配合 CSP 防 XSS
HttpOnly Cookie
- ✅ JS 读不到 = 防 XSS 偷
- ✅ 自动带请求
- ❌ 自动带 = 易受 CSRF
- 适合:配合 SameSite 防 CSRF
推荐方案: accessToken 存内存(JS 变量,刷新页丢,防 XSS),refreshToken 存 HttpOnly Cookie(防 XSS 偷,防 CSRF 用 SameSite)。兼顾安全与体验。
6
其他安全威胁
| 威胁 | 原理 | 防御 |
|---|---|---|
| 点击劫持 | 恶意网站用透明 iframe 套你的页面,诱导点击 | X-Frame-Options: DENY / CSP frame-ancestors |
| 供应链投毒 | npm 包被植入恶意代码 | npm audit + 锁版本 + Snyk 扫描 |
| 中间人攻击 | 网络层截获/篡改请求 | HTTPS 全站 + HSTS |
| 开放重定向 | redirect 参数可控,钓鱼 | 校验重定向地址白名单 |
| 敏感信息泄露 | token/密钥写在前端代码 | 敏感操作放后端,前端不存密钥 |
7
高频追问
1什么是 XSS?怎么防? 必问
跨站脚本攻击,注入恶意脚本在用户浏览器执行。三种:存储型(最严重,存库)、反射型(URL 参数)、DOM 型(纯前端)。防御:① 输出转义(Vue {{}} 默认安全,v-html 危险);② 必须 v-html 用 DOMPurify 清洗;③ CSP 限制脚本来源;④ HttpOnly Cookie 防 token 被偷。
2XSS 和 CSRF 区别? 高频
XSS 是注入脚本执行(在你网站内),防靠转义/清洗;CSRF 是冒充你发请求(从别的网站,借你的 cookie),防靠 token/SameSite。XSS 偷你的东西,CSRF 借你的身份。两者常结合:先用 XSS 偷 token,再 CSRF。
3token 存 localStorage 还是 cookie? 高频
各有利弊。localStorage 易 XSS(JS 可读),HttpOnly Cookie 防 XSS 偷但易 CSRF(自动带请求)。推荐:accessToken 存内存(刷新页丢,防 XSS),refreshToken 存 HttpOnly Cookie(防 XSS 偷 + SameSite 防 CSRF)。没有完美方案,是权衡。
4CSP 怎么防 XSS? 中等
通过 HTTP 头限制只允许从白名单域加载脚本。即使有 XSS,恶意脚本(非白名单域)也无法加载执行。配合禁止 inline script 和 eval,堵死大部分 XSS。是 XSS 最后一道防线。上线前用 Report-Only 模式观察避免误伤。
5水平越权和垂直越权? 中等
水平越权(IDOR): 同级别用户互相越权(改 URL userId 看 B 的数据)。垂直越权: 普通用户调管理员接口。防御核心都在后端: 每个接口校验资源归属 + 角色权限。前端隐藏菜单只是体验,防不住越权(用户可绕过前端直接调接口)。
6Vue 的 v-html 危险在哪? 基础
v-html 直接把字符串当 HTML 渲染,不转义。如果内容用户可控(评论/富文本/LLM 输出),攻击者可注入 <script> 执行任意 JS。必须 DOMPurify 清洗后才 v-html。Vue 模板 {{}} 是安全的(自动转义 HTML 实体)。
8
30 秒陈述
🎤 30 秒版
「前端安全我有实战意识。做 LLM 对话,模型输出一定 DOMPurify 清洗才 v-html,防 XSS;富文本粘贴 Word 内容白名单过滤;多租户系统我反复强调前端隔离只是体验,数据安全命门在后端校验每个接口的资源归属,防越权 IDOR。token 我倾向 accessToken 内存 + refreshToken HttpOnly Cookie,权衡 XSS 和 CSRF。CSP 配白名单做 XSS 最后一道防线。」