WebGoat问题复现:手把手教你演示XSS攻击
引言:为何XSS仍是开发者的噩梦?
你是否遇到过这样的场景:用户输入的昵称在页面上显示时触发了弹窗?或者点击某个链接后浏览器执行了未知脚本?这些都是跨站脚本攻击(Cross-Site Scripting, XSS)的典型表现。作为OWASP Top 10中常年占据一席之地的问题类型,XSS至今仍在各类Web应用中频繁出现。本教程将以WebGoat(一个故意设计存在安全问题的Web应用)为实验环境,通过3个实战场景带你全面掌握XSS问题的发现与利用方法。
读完本文你将掌握:
- 反射型XSS在购物车场景中的利用技巧
- DOM型XSS的参数污染攻击手段
- 存储型XSS的持久化攻击流程
- 3种XSS类型的防御策略对比
环境准备:5分钟搭建问题测试平台
1. 快速部署WebGoat
WebGoat提供多种部署方式,推荐使用Docker容器化部署以确保环境一致性:
# 启动WebGoat主应用和配套工具WebWolf
docker run -it -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 webgoat/webgoat
注意:映射端口限制为本地回环地址(127.0.0.1)可防止问题被外部网络利用,符合安全测试最佳实践。
2. 验证环境可用性
访问http://localhost:8080/WebGoat,完成注册并登录。在左侧课程列表中找到"Cross-Site Scripting"模块,展开后可见5个实战课程,本文将重点演示其中3个典型场景。
场景一:反射型XSS——购物车金额计算问题
问题原理剖析
在CrossSiteScriptingLesson5a.java中,控制器对信用卡号字段(field1)的输入验证存在缺陷:
// 关键验证逻辑
if (XSS_PATTERN.test(field1)) {
userSessionData.setValue("xss-reflected-5a-complete", "true");
if (field1.toLowerCase().contains("console.log")) {
return success(this).feedback("xss-reflected-5a-success-console").build();
} else {
return success(this).feedback("xss-reflected-5a-success-alert").build();
}
}
其中XSS_PATTERN定义为:
Pattern.compile(".*<script>(console\\.log|alert)\\(.*\\);?</script>.*", Pattern.CASE_INSENSITIVE)
这意味着只要在信用卡号字段注入包含<script>标签且包含console.log或alert函数的脚本,即可绕过验证并执行。
攻击步骤实战
-
访问购物车页面
导航至Cross-Site Scripting→Reflected XSS (5a)课程页面 -
构造恶意输入
在"Credit Card Number"字段输入:<script>alert('XSS')</script>其他商品数量字段随意填写数字(如1)
-
触发问题
提交表单后,页面将执行注入的脚本并显示弹窗,同时服务器返回成功信息:xss-reflected-5a-success-alert
高级利用技巧
| 攻击载荷 | 效果 | 绕过策略 |
|---|---|---|
<script>alert(1)</script> | 基础弹窗 | 直接匹配标签 |
<script>console.log(document.cookie)</script> | 窃取Cookie | 利用控制台输出 |
<img src=x onerror=alert(1)> | 无脚本标签 | 事件驱动执行 |
注意:WebGoat的XSS过滤器已拦截事件驱动型载荷,仅允许
<script>标签内的特定函数。
场景二:DOM型XSS——参数污染攻击
问题代码分析
DOMCrossSiteScripting.java中存在DOM型XSS问题,控制器通过请求头验证来源:
@PostMapping("/CrossSiteScripting/phone-home-xss")
public AttackResult completed(
@RequestParam Integer param1,
@RequestParam Integer param2,
HttpServletRequest request) {
if (param1 == 42 && param2 == 24 &&
request.getHeader("webgoat-requested-by").equals("dom-xss-vuln")) {
return success(this).build();
}
}
前端JavaScript可能存在以下不安全代码(根据控制器逻辑推断):
var url = new URL(window.location.href);
var param = url.searchParams.get('testParam');
document.getElementById('output').innerHTML = param;
攻击实施步骤
-
构造恶意URL
在浏览器中访问:http://localhost:8080/WebGoat/start.mvc#test/testParam=<script>webgoat.customjs.phoneHome()</script> -
触发DOM解析
页面JavaScript会将URL中的testParam参数值直接插入DOM,导致脚本执行,调用phoneHome()函数向服务器发送请求。 -
验证攻击成功
服务器接收到请求头webgoat-requested-by: dom-xss-vuln后返回成功响应:{"lessonCompleted": true, "output": "phoneHome Response is 12345"}
DOM型vs反射型对比
关键区别:DOM型XSS的问题完全在客户端,服务器不参与恶意代码的返回过程。
场景三:存储型XSS——评论系统持久化攻击
问题实现机制
StoredXssComments.java实现了存储型XSS功能,服务器将用户评论直接存入内存并返回给所有访问者:
@PostMapping("/CrossSiteScriptingStored/stored-xss")
public AttackResult createNewComment(@RequestBody String commentStr) {
Comment comment = parseJson(commentStr);
comments.add(comment); // 直接存储未过滤的评论
if (comment.getText().contains("<script>webgoat.customjs.phoneHome()</script>")) {
return success(this).build();
}
}
完整攻击流程
-
提交恶意评论
发送POST请求至/CrossSiteScriptingStored/stored-xss:{ "text": "<script>webgoat.customjs.phoneHome()</script>" } -
数据持久化
服务器将包含恶意脚本的评论存入comments列表,所有访问该页面的用户都会加载此评论。 -
触发攻击链
当其他用户访问评论页面时,脚本自动执行并调用phoneHome()函数,完成攻击指标收集。
危害分析
存储型XSS具有持续性和传播性,单个注入可影响所有后续访问者,危害远高于反射型和DOM型。
环境搭建指南
Docker快速部署
# 标准部署(推荐)
docker run -it -p 127.0.0.1:8080:8080 -p 127.0.0.1:9090:9090 webgoat/webgoat
# 带桌面环境(适合新手)
docker run -p 127.0.0.1:3000:3000 webgoat/webgoat-desktop
注意:生产环境严禁暴露WebGoat到公网,测试完成后立即停止容器。
手动编译运行
# 克隆仓库
git clone https://gitcode.com/GitHub_Trending/we/WebGoat
cd WebGoat
# 编译项目
./mvnw clean install
# 启动服务
./mvnw spring-boot:run
防御策略对比
| 防御措施 | 实现难度 | 防护范围 | 适用场景 |
|---|---|---|---|
| 输入验证 | 低 | 部分 | 已知输入格式 |
| 输出编码 | 中 | 全面 | 动态内容渲染 |
| CSP策略 | 高 | 全面 | 现代浏览器环境 |
| HttpOnly Cookie | 低 | 会话保护 | 认证系统 |
代码修复示例
输出编码实现(Java):
// 使用OWASP编码器
import org.owasp.encoder.Encode;
String safeHtml = Encode.forHtml(userInput);
response.getWriter().write(safeHtml);
内容安全策略(CSP):
Content-Security-Policy: default-src 'self'; script-src 'none'
总结与展望
通过WebGoat的3个典型场景,我们系统演示了XSS问题的发现、利用与防御全流程。从反射型的即时触发,到DOM型的客户端解析,再到存储型的持久化攻击,每种类型都有其独特的利用方式和防御要点。
关键收获:
- XSS问题本质是未验证的用户输入被当作代码执行
- 防御需采用"输入验证+输出编码+CSP"的多层策略
- WebGoat提供的受控环境是安全学习的理想平台
后续学习路线:
- XSS与CSRF组合攻击
- 基于机器学习的XSS检测
- 浏览器内置安全机制绕过技术
收藏本文,关注更新,下期将带来"WebGoat SQL注入攻防实战"。如有疑问或建议,欢迎在评论区留言讨论。
参考资料
- OWASP XSS攻击防御 cheat sheet
- WebGoat官方文档(https://gitcode.com/GitHub_Trending/we/WebGoat)
- 《Web应用安全权威指南》XSS章节
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



