XSS攻击类型与前端防御方案
详细解释跨站脚本攻击(XSS)的三种类型(反射型/存储型/DOM型)的原理、危害,以及前端开发者需要采取哪些防御措施(CSP、输入输出编码、HttpOnly等)。
回答
孤独的心
XSS三种类型
1. 反射型XSS
- 恶意脚本在URL中,服务端直接反射到响应页面
- 示例:
https://example.com/search?q=<script>alert(1)</script> - 需要用户点击恶意链接
2. 存储型XSS(最危险)
- 恶意脚本存储到服务器数据库
- 每次正常访问页面都触发(如评论区/用户资料)
- 示例:用户评论写入
<script>stealCookie()</script>
3. DOM型XSS
- 纯前端漏洞,不经过服务端
- 通过innerHTML、document.write、eval等将用户输入作为HTML执行
- 示例:
element.innerHTML = userInput(含恶意脚本)
防御措施
1. 输入编码(Output Encoding)
- HTML实体编码:
<→<,>→>,"→" - React/Vue自动处理(dangerouslySetInnerHTML/v-html需谨慎)
- 不同上下文用不同编码(HTML/JS/CSS/URL)
2. 内容安全策略(CSP)
Content-Security-Policy: default-src 'self'; script-src 'self';
- 限制可执行的脚本来源
- 禁止内联脚本(
'unsafe-inline')和内联事件 - 即使注入script标签也不会执行
3. HttpOnly Cookie
Set-Cookie: sessionId=xxx; HttpOnly; Secure; SameSite=Strict
- 禁止JS访问Cookie(
document.cookie无效) - 防御Cookie窃取
4. 输入验证与过滤
- 根据场景限制输入类型(数字/邮箱/URL)
- 不要自行实现HTML净化器(使用DOMPurify库)
- 富文本场景使用白名单标签/属性
5. 其他措施
- 使用
X-XSS-Protection: 1; mode=block(已废弃但兼容) - 避免
eval()/new Function()/setTimeout(string) - React中避免
dangerouslySetInnerHTML - Vue中避免
v-html,使用Markdown替代
前沿方案:
- Trusted Types(Chrome):强制要求经过信任的HTML才可设置到innerHTML等
- React 18中自动转义引用类型
- SPA框架默认编码机制({data}自动转义)