跨站脚本攻击(XSS)允许攻击者通过注入恶意脚本到网站页面并窃取用户数据或劫持会话,以下是分层的防御策略,涵盖开发、测试和部署全流程。 一、理解 XSS 类型反射型 XSS 存储型 XSS DOM 型 XSS 二、输入处理与验证严格输入过滤 白名单原则:仅允许已知安全的字符或格式(如:数字、字母、有限的标点)。
示例代码(Python): import re
def sanitize_input(input_str):
# 仅允许字母、数字、空格和基本标点
return re.sub(r'[^a-zA-Z0-9\s.,!?]', '', input_str)
处理富文本内容 使用安全库清理 HTML:
JavaScript:DOMPurify.sanitize(dirty_html) Python:bleach.clean(text, tags=['p', 'a'], attributes={'a': ['href']})
配置允许的标签与属性:
// 允许 <a> 标签的 href 属性,但禁止 javascript: 协议
const clean = DOMPurify.sanitize(dirty, {
ALLOWED_TAGS: ['a', 'p'],
ALLOWED_ATTR: ['href'],
FORBID_ATTR: ['style', 'onclick'],
FORBID_URI_REGEX: /^javascript:/i
});
编码特殊字符 服务器端转义(如:PHP): $safe_output = htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
三、输出编码与上下文处理根据输出位置选择正确的编码方式: 输出上下文 | 编码方法 | 示例(原始输入:user_input = '<script>') | HTML 正文 | 转义 <, >, &, ", ' | <script> | HTML 属性 | 转义 " 和 ',使用引号包裹属性值 | <div title="用户输入"value""> | JavaScript 变量 | Unicode 转义或 JSON 序列化 | var data = "\u003Cscript\u003E"; | URL 参数 | URL 编码(百分比编码) | redirect?param=https%3A%2F%2Fexample.com | CSS 样式 | 转义特殊字符并使用 \ 编码 | color: \3c script\3e ; | 框架自动转义示例
React: // 自动转义,输出文本
<div>{userInput}</div>
// 危险操作需显式净化
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userInput) }} />
Django 模板: <!-- 自动转义 -->
{{ user_input }}
<!-- 关闭转义需手动处理 -->
{% autoescape off %}
{{ sanitized_input|safe }}
{% endautoescape %}
四、内容安全策略(CSP)通过 HTTP 头限制资源加载,阻止未经授权的脚本执行。 基础配置 Content-Security-Policy:
default-src 'self';
script-src 'self' https://www.seogongguan.com 'nonce-ABC123';
style-src 'self' 'unsafe-inline';
img-src *;
object-src 'none';
report-uri /csp-report;
Nonce或Hash白名单
Nonce(一次性随机值): <script nonce="ABC123">
// 合法脚本
</script>
Hash(脚本内容哈希): Content-Security-Policy: script-src 'sha256-abc123...'
五、安全Cookie和HTTP 头
HttpOnly和Secure Cookie Set-Cookie: sessionId=123; HttpOnly; Secure; SameSite=Lax
安全响应头
X-Content-Type-Options: nosniff:禁止浏览器猜测MIME类型。 X-Frame-Options: DENY:阻止页面被嵌入iframe。 Referrer-Policy: strict-origin-when-cross-origin:限制Referrer信息泄露。
六、防御DOM型XSS
避免危险API - 禁止直接使用 innerHTML、outerHTML、document.write()。
使用安全的 DOM 操作方法: // 错误示例- element.innerHTML = userInput;
- // 正确做法
- element.textContent = userInput;
安全处理URL参数 // 错误示例(直接使用 location.hash) const data = location.hash.substring(1); element.innerHTML = data; // 正确做法(URL 解码并转义) const params = new URLSearchParams(window.location.search); const input = params.get('data'); element.textContent = input;
使用安全库解析内容 // 使用DOMPurify清理动态内容 const userContent = DOMPurify.sanitize(unsafeContent, { RETURN_TRUSTED_TYPE: true }); element.innerHTML = userContent;
七、测试与监控自动化扫描工具
单元测试与代码审查
漏洞赏金与渗透测试
八、框架与库的最佳实践// 自动转义内容
<div>{userInput}</div>
// 使用 dangerouslySetInnerHTML 时需手动净化
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userInput) }} />
Angular: // 自动转义插值
{{ userInput }}
// 使用 DomSanitizer 显式信任内容
import { DomSanitizer } from '@angular/platform-browser';
constructor(private sanitizer: DomSanitizer) {}
safeHtml = this.sanitizer.bypassSecurityTrustHtml(dirtyHtml);
九、常见误区与陷阱依赖客户端验证
错误编码上下文
过度信任第三方依赖
十、进阶防护措施Web 应用防火墙(WAF)
沙盒隔离用户生成内容
实时输入监控
通过结合输入验证、输出编码、CSP、安全头设置和严格测试,可构建多层防御体系,显著降低 XSS 风险。防御需贯穿开发全生命周期,并持续更新应对新型攻击手法。 |