前端安全:XSS 与 CSP 实战
用户输入直接插到页面里?那 XSS 已经在路上了。本文讲清 XSS 攻击原理、输出编码防御和 CSP 内容安全策略的正确配置。
一、XSS 是什么
XSS(跨站脚本)是攻击者把恶意脚本注入到网页里,当其他用户访问时脚本在浏览器执行。典型场景:评论区输入 <script>stealCookies()</script>,如果网站没做转义,所有看评论的用户都会中招。
| 类型 | 原理 | 示例 |
|---|---|---|
| 存储型 | 恶意脚本存到服务器 | 评论、留言板 |
| 反射型 | 恶意脚本在 URL 参数里 | 搜索结果回显 |
| DOM 型 | 前端 JS 直接插入 HTML | innerHTML 渲染用户输入 |
二、防御:输出编码
// 危险:直接插入 HTML
element.innerHTML = userInput;
// 安全:用 textContent(自动转义)
element.textContent = userInput;
// 安全:手动转义
function escapeHtml(str) {
return str
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
element.innerHTML = escapeHtml(userInput);
核心原则:永远不要信任用户输入。在把用户数据插入 HTML 之前,必须转义。用 textContent 代替 innerHTML 是最简单的防御。
三、CSP 内容安全策略
CSP 是浏览器层面的安全防线,告诉浏览器哪些脚本可以执行、哪些来源可以加载资源。即使攻击者注入了脚本,CSP 也会阻止它执行。
<!-- 在 HTML head 里加 meta 标签 -->
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self' https://cdn.example.com;
style-src 'self' 'unsafe-inline';
img-src 'self' https:* data:;
object-src 'none';">
四、CSP 常用指令
default-src 'self' 默认只允许同源
script-src 'self' cdn.js.org 只允许这些来源的脚本
style-src 'self' 'unsafe-inline' 样式(内联样式需要 unsafe-inline)
img-src 'self' data: https: 图片允许 data: 和 https
object-src 'none' 禁止 Flash 等插件
frame-src 'none' 禁止 iframe
五、HttpOnly Cookie
Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict
HttpOnly 标记让 JS 无法读取 Cookie。即使 XSS 成功注入脚本,攻击者也偷不到 sessionId。Secure 要求 HTTPS 传输。SameSite=Strict 阻止跨站请求携带 Cookie。
六、其他安全措施
第一,富文本编辑器要用 DOMPurify 等库做白名单过滤,不能直接用 innerHTML。第二,登录状态用 CSRF Token 验证,防止跨站请求伪造。第三,敏感操作加二次确认,比如删除账号要输密码。
七、总结
前端安全三层防线:第一层输出编码(textContent / escapeHtml),第二层 CSP(白名单限制脚本来源),第三层 HttpOnly Cookie(即使 XSS 成功也偷不到会话)。记住:永远不信任用户输入,纵深防御。