【Java 代码审计入门-03】XSS 漏洞原理与实际案例介绍
字数 1035 2025-08-25 22:58:46

Java代码审计入门:XSS漏洞原理与实际案例详解

0x00 前言

本系列文章旨在为具备Java基本语法基础的学习者提供系统的Java代码审计教程。本文是第三篇,重点讲解XSS漏洞的原理与实际案例分析。

0x01 XSS漏洞基础

XSS漏洞定义

XSS(跨站脚本攻击)是通过对网页插入可执行代码且成功被浏览器执行,达到攻击目的的安全漏洞。XSS攻击的危害包括但不限于:

  • 获取用户Cookies
  • 获取用户联系人列表
  • 屏幕截取
  • 会话劫持等

XSS类型分类

  1. 反射型XSS:非持久化,需要欺骗用户点击恶意链接
  2. 存储型XSS:持久化,恶意代码存储在服务器端
  3. DOM型XSS:通过修改DOM环境在客户端直接触发

0x02 反射型XSS案例

漏洞代码示例

public void Message(HttpServletRequest req, HttpServletResponse resp) {
    String message = req.getParameter("msg");
    try {
        resp.getWriter().print(message);  // 直接输出用户输入
    } catch (IOException e) {
        e.printStackTrace();
    }
}

攻击原理

  1. 攻击者构造恶意URL:http://example.com/page?msg=<script>alert('xss')</script>
  2. 服务器直接返回未过滤的用户输入
  3. 浏览器执行恶意脚本

漏洞验证

输入<script>alert('xss')</script>,浏览器会弹出警告框。

0x03 存储型XSS案例

漏洞代码分析

  1. 数据存储部分
public void StoreXss(HttpServletRequest req, HttpServletResponse resp) {
    String name = req.getParameter("name");
    String mail = req.getParameter("mail");
    String message = req.getParameter("message");
    if(!name.equals(null) && !mail.equals(null) && !message.equals(null)){
        MessageInfoService msginfo = new MessageInfoServiceImpl();
        msginfo.MessageInfoStoreService(name, mail, message);  // 存储未过滤的用户输入
    }
}
  1. 数据展示部分
<% List<MessageInfo> msginfo = (ArrayList<MessageInfo>)request.getAttribute("msg");
for(MessageInfo m : msginfo){ %>
<td class="hvttd"><%= m.getMessage() %></td>  <!-- 直接输出数据库内容 -->
<% } %>

攻击流程

  1. 攻击者提交包含恶意脚本的表单数据
  2. 数据被存储到数据库
  3. 其他用户访问页面时,恶意脚本从数据库取出并执行

0x04 XSS防御方案

1. 全局过滤器方案

web.xml配置

<filter>
    <filter-name>XssSafe</filter-name>
    <filter-class>XssFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>XssSafe</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

过滤器实现

public class XssFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                         FilterChain chain) throws IOException, ServletException {
        chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest)request), response);
    }
}

XSS过滤逻辑

private String xssClean(String value) {
    if (value != null) {
        // 过滤script标签
        value = value.replaceAll("(?i)<script>(.*?)</script>", "");
        // 过滤src属性
        value = value.replaceAll("src[\r\n]*=[\r\n]*\\'(.*?)\\'", "");
        // 过滤javascript:表达式
        value = value.replaceAll("javascript:", "");
        // 过滤事件处理函数
        value = value.replaceAll("onload(.*?)=", "");
    }
    return value;
}

2. 使用xssProtect工具

protected String protectedAgainstXSS(String html) {
    StringReader reader = new StringReader(html);
    StringWriter writer = new StringWriter();
    try {
        HTMLParser.process(reader, writer, new XSSFilter(), true);
        return writer.toString();
    } catch (HandlingException e) {
        return "";
    }
}

3. 使用Apache Commons Lang

// HTML转义
String safeOutput = StringEscapeUtils.escapeHtml(input);
// JavaScript转义
String safeJS = StringEscapeUtils.escapeJavaScript(input);

0x05 实际案例:CVE-2018-19178分析

漏洞描述

JEESNS 1.3中存在XSS漏洞,攻击者可通过<embed>标签绕过过滤插入恶意代码。

漏洞代码

private String cleanXSS(String value) {
    // 过滤style和script标签
    value = value.replaceAll("(?i)<style>", "&lt;style&gt;")
                .replaceAll("(?i)</style>", "&lt;&#47;style&gt;");
    value = value.replaceAll("(?i)<script>", "&lt;script&gt;")
                .replaceAll("(?i)</script>", "&lt;&#47;script&gt;");
    
    // 过滤事件处理函数
    String[] eventKeywords = {"onmouseover", "onclick", "onload", "alert"};
    for (String keyword : eventKeywords) {
        value = value.replaceAll(keyword, "_" + keyword);
    }
    return value;
}

绕过方式

  1. 使用<embed>标签:
<embed src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">
  1. 使用SVG标签:
<svg/onLoad=confirm(1)>

修复建议

  1. 采用更全面的标签过滤策略
  2. 使用白名单而非黑名单方式
  3. 结合HTML实体编码

0x06 总结

XSS漏洞防御要点:

  1. 输入验证:对用户输入进行严格验证
  2. 输出编码:在输出到页面时进行适当的编码
  3. 内容安全策略(CSP):使用HTTP头限制脚本执行
  4. HttpOnly标志:为Cookie设置HttpOnly属性

通过本教程,您应该已经掌握了Java Web应用中XSS漏洞的原理、检测方法和防御策略。在实际审计过程中,需要特别注意所有用户输入点和数据输出点,确保数据流动过程中有适当的过滤和编码处理。

Java代码审计入门:XSS漏洞原理与实际案例详解 0x00 前言 本系列文章旨在为具备Java基本语法基础的学习者提供系统的Java代码审计教程。本文是第三篇,重点讲解XSS漏洞的原理与实际案例分析。 0x01 XSS漏洞基础 XSS漏洞定义 XSS(跨站脚本攻击)是通过对网页插入可执行代码且成功被浏览器执行,达到攻击目的的安全漏洞。XSS攻击的危害包括但不限于: 获取用户Cookies 获取用户联系人列表 屏幕截取 会话劫持等 XSS类型分类 反射型XSS :非持久化,需要欺骗用户点击恶意链接 存储型XSS :持久化,恶意代码存储在服务器端 DOM型XSS :通过修改DOM环境在客户端直接触发 0x02 反射型XSS案例 漏洞代码示例 攻击原理 攻击者构造恶意URL: http://example.com/page?msg=<script>alert('xss')</script> 服务器直接返回未过滤的用户输入 浏览器执行恶意脚本 漏洞验证 输入 <script>alert('xss')</script> ,浏览器会弹出警告框。 0x03 存储型XSS案例 漏洞代码分析 数据存储部分 : 数据展示部分 : 攻击流程 攻击者提交包含恶意脚本的表单数据 数据被存储到数据库 其他用户访问页面时,恶意脚本从数据库取出并执行 0x04 XSS防御方案 1. 全局过滤器方案 web.xml配置 : 过滤器实现 : XSS过滤逻辑 : 2. 使用xssProtect工具 3. 使用Apache Commons Lang 0x05 实际案例:CVE-2018-19178分析 漏洞描述 JEESNS 1.3中存在XSS漏洞,攻击者可通过 <embed> 标签绕过过滤插入恶意代码。 漏洞代码 绕过方式 使用 <embed> 标签: 使用SVG标签: 修复建议 采用更全面的标签过滤策略 使用白名单而非黑名单方式 结合HTML实体编码 0x06 总结 XSS漏洞防御要点: 输入验证 :对用户输入进行严格验证 输出编码 :在输出到页面时进行适当的编码 内容安全策略(CSP) :使用HTTP头限制脚本执行 HttpOnly标志 :为Cookie设置HttpOnly属性 通过本教程,您应该已经掌握了Java Web应用中XSS漏洞的原理、检测方法和防御策略。在实际审计过程中,需要特别注意所有用户输入点和数据输出点,确保数据流动过程中有适当的过滤和编码处理。