XSS 攻击防护
使用场景
检查代码中的 XSS 漏洞并提供修复方案。
XSS 类型
1. 反射型 XSS
URL: https://example.com/search?q=<script>alert(1)</script>
页面直接输出 q 参数,导致脚本执行
2. 存储型 XSS
用户提交的评论包含恶意脚本
其他用户查看评论时脚本执行
3. DOM 型 XSS
// 危险:直接操作 DOM
document.getElementById('output').innerHTML = location.hash.slice(1);
防护方法(按优先级)
1. Content-Security-Policy(CSP)— 最重要
# 严格 CSP — 阻止内联脚本执行
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'
# 允许特定 CDN
Content-Security-Policy: script-src 'self' https://cdn.example.com
CSP 是浏览器级别的防护,即使存在 XSS 漏洞也能阻止脚本执行。优先配置。
2. 输出编码 / 转义
// 前端:HTML 转义
function escapeHtml(text) {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return text.replace(/[&<>"']/g, m => map[m]);
}
// 安全做法:使用 textContent 而非 innerHTML
element.textContent = userInput; // 安全
element.innerHTML = userInput; // 危险 — 除非已经过 sanitize
# 后端:使用模板引擎自动转义
# Jinja2 默认开启自动转义;确保未被标记为 safe
from markupsafe import escape
safe_content = escape(user_input)
3. Trusted Types(现代浏览器)
// 配合 CSP: require-trusted-types-for 'script'
// 强制所有 DOM XSS sink 使用 Trusted Types API
const policy = trustedTypes.createPolicy('default', {
createHTML: (str) => DOMPurify.sanitize(str)
});
element.innerHTML = policy.createHTML(userInput);
4. DOMPurify(需要 innerHTML 时)
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userInput);
5. Cookie 安全属性
Set-Cookie: session=abc; HttpOnly; Secure; SameSite=Strict
HttpOnly:JS 无法读取 cookie(防止 cookie 窃取)Secure:仅通过 HTTPS 发送SameSite=Strict:阻止跨站请求携带 cookie
6. 安全响应头
Content-Security-Policy: ...
X-Content-Type-Options: nosniff
关于
X-XSS-Protection: 该响应头已被废弃。现代浏览器已移除其内建的 XSS auditor,设为1; mode=block反而在某些旧浏览器中可能引入新的攻击向量。不要使用它,改用 CSP。
检查清单
- 配置了 Content-Security-Policy
- 所有用户输入在输出时做了转义
- 不使用 innerHTML 插入未消毒的用户内容
- Cookie 设置了 HttpOnly + Secure + SameSite
- API 响应设置了正确的 Content-Type
- 第三方内容使用 sandbox iframe
- 考虑启用 Trusted Types(如果目标浏览器支持)
- 未使用
X-XSS-Protection
