Java代码审计之XSS
字数 1639 2025-08-12 11:33:56
Java代码审计之XSS漏洞详解与防御
一、XSS漏洞原理
XSS(Cross-Site Scripting)跨站脚本攻击是指攻击者通过在网页中注入恶意脚本代码,当用户浏览该页面时,嵌入其中的恶意代码会被执行,从而达到攻击目的。
XSS攻击通常利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页。这些恶意网页程序通常是JavaScript,但也可以包括Java、VBScript、ActiveX、Flash或普通HTML。
二、XSS攻击类型
1. 反射型XSS
反射型XSS是非持久化的,需要欺骗用户自己去点击带有特定参数的链接才能触发。
示例代码:
@RequestMapping("/reflect")
@ResponseBody
public static String reflect(String xss) {
return xss;
}
攻击方式:
- 构造恶意URL:
http://example.com/reflect?xss=<script>alert(1)</script> - 当用户访问该URL时,服务器直接将参数xss的值返回给页面,导致JavaScript代码被执行
2. 存储型XSS
存储型XSS是持久化的,恶意代码被存储在服务器中(如数据库、文件、Cookie等),每当用户访问包含该恶意代码的页面时就会触发。
示例代码:
@RequestMapping("/stored/store")
@ResponseBody
public String store(String xss, HttpServletResponse response) {
Cookie cookie = new Cookie("xss", xss);
response.addCookie(cookie);
return "Set param into cookie";
}
@RequestMapping("/stored/show")
@ResponseBody
public String show(@CookieValue("xss") String xss) {
return xss;
}
攻击方式:
- 首先访问
/stored/store接口存储恶意代码到Cookie:
http://example.com/stored/store?xss=<script>alert(1)</script> - 然后访问
/stored/show接口,服务器从Cookie中读取并返回恶意代码,导致XSS执行
三、XSS攻击的危害
- 网络蠕虫攻击:通过漏洞点嵌入恶意JS代码,执行后会添加带有恶意代码的页面或DOM元素,实现自我传播
- 窃取用户Cookie:通过跨域请求盗取用户认证信息
- 会话劫持:获取用户会话令牌,冒充用户身份
- 钓鱼攻击:伪造登录表单诱导用户输入敏感信息
- 键盘记录:记录用户的键盘输入
四、XSS漏洞防御
1. 输入过滤与转义
对所有不可信数据进行HTML实体编码:
@RequestMapping("/safe")
@ResponseBody
public static String safe(String xss) {
return encode(xss);
}
private static String encode(String origin) {
origin = StringUtils.replace(origin, "&", "&");
origin = StringUtils.replace(origin, "<", "<");
origin = StringUtils.replace(origin, ">", ">");
origin = StringUtils.replace(origin, "\"", """);
origin = StringUtils.replace(origin, "'", "'");
origin = StringUtils.replace(origin, "/", "/");
return origin;
}
2. 防御措施详解
-
HTML实体编码:
- 将特殊字符转换为HTML实体
- 必须转义的字符:
&,<,>,",',/
-
使用安全框架:
- Spring框架的
HtmlUtils.htmlEscape() - OWASP ESAPI的
Encoder.encodeForHTML()
- Spring框架的
-
HTTP头设置:
response.setHeader("X-XSS-Protection", "1; mode=block"); response.setHeader("Content-Security-Policy", "default-src 'self'"); -
HttpOnly Cookie:
Cookie cookie = new Cookie("name", "value"); cookie.setHttpOnly(true); -
输入验证:
- 对用户输入进行严格的白名单验证
- 使用正则表达式过滤特殊字符
五、进阶防御技巧
-
上下文相关编码:
- HTML内容:
&,<,>,",',/ - HTML属性:除HTML内容外还需注意空格和换行
- JavaScript:使用
\xXX形式编码 - URL:使用百分比编码
- HTML内容:
-
CSP(Content Security Policy):
response.setHeader("Content-Security-Policy", "default-src 'none'; script-src 'self' 'unsafe-inline'"); -
输出编码库选择:
- OWASP Java Encoder项目
- Apache Commons Text的
StringEscapeUtils
六、审计要点
-
查找所有用户输入点:
- 请求参数(
@RequestParam,@PathVariable) - 表单数据(
@ModelAttribute) - Cookie(
@CookieValue) - 请求头(
@RequestHeader)
- 请求参数(
-
检查输出点:
- 直接返回用户输入的接口(
@ResponseBody) - JSP/Thymeleaf模板中的
${}表达式 - JavaScript中的动态拼接
- 直接返回用户输入的接口(
-
验证防护措施:
- 是否对所有不可信数据进行了编码
- 编码是否完整(所有危险字符都被处理)
- 是否使用了安全的框架方法
七、测试用例
-
基本测试:
<script>alert(1)</script> -
大小写混淆:
<ScRiPt>alert(1)</ScRiPt> -
无闭合标签:
-
编码绕过:
-
SVG向量:
<svg/onload=alert(1)> -
JavaScript伪协议:
<a href="javascript:alert(1)">click</a>
通过全面理解XSS漏洞原理、攻击方式和防御措施,开发人员可以在代码审计和开发过程中有效预防XSS漏洞,保障Web应用安全。