JAVA代码审计-StudentManager
字数 1301 2025-08-22 12:23:06

Java代码审计实战:StudentManager系统漏洞分析与修复指南

一、系统概述

StudentManager是一个基于Java Web的学生管理系统,使用Servlet+JSP架构,存在多处严重安全漏洞。本指南将详细分析这些漏洞的原理、危害及修复方案。

二、SQL注入漏洞

1. 漏洞位置与原理

系统在多个DAO类中直接拼接SQL语句,未使用预编译:

StudentD.java

public Student checkAccount(String user, String password) throws Exception {
    initConnection();
    Statement stat = conn.createStatement();
    String sql = "select * from student where id = '" + user + "' and password = '" + password + "'";
    ResultSet rs = stat.executeQuery(sql);
    Student stu = getStudent(rs);
    closeConnection();
    return stu;
}

TeacherD.java

public Teacher checkAccount(String id, String password) throws Exception {
    initConnection();
    Statement stat = conn.createStatement();
    String sql = "select * from teacher where id = '" + id + "' and password = '" + password + "'";
    ResultSet rs = stat.executeQuery(sql);
    Teacher tea = getTeacher(rs);
    closeConnection();
    return tea;
}

2. 漏洞利用方式

登录处注入Payload:

用户名:admin'or 1=1#
密码:任意值

3. 影响范围

  • StudentD类中的方法:

    • checkAccount
    • findWithId
    • findWithName
    • deleteStudent
  • TeacherD类中的方法:

    • checkAccount
    • findWithId

4. 修复方案

使用PreparedStatement进行参数化查询:

public Student checkAccount(String user, String password) throws Exception {
    initConnection();
    String sql = "select * from student where id = ? and password = ?";
    PreparedStatement ps = conn.prepareStatement(sql);
    ps.setString(1, user);
    ps.setString(2, password);
    ResultSet rs = ps.executeQuery();
    Student stu = getStudent(rs);
    closeConnection();
    return stu;
}

三、越权访问漏洞

1. 漏洞位置

在main.jsp页面中仅简单获取session信息,未进行权限验证:

student/main.jsp

<% Student student = (Student) session.getAttribute("info");%>

teacher/main.jsp

<% Teacher teacher = (Teacher) session.getAttribute("info"); 
   ArrayList<Student> stus = (ArrayList<Student>) session.getAttribute("onePageStudent"); 
   int sumIndex = (int) session.getAttribute("sumIndex");%>

2. 漏洞危害

攻击者无需登录即可直接访问敏感页面,虽然会报500错误,但仍暴露系统结构信息。

3. 修复方案

添加权限验证过滤器:

public class AuthFilter implements Filter {
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
        throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        HttpSession session = req.getSession(false);
        
        if (session == null || session.getAttribute("info") == null) {
            res.sendRedirect(req.getContextPath() + "/login.jsp");
            return;
        }
        chain.doFilter(request, response);
    }
}

在web.xml中配置过滤器:

<filter>
    <filter-name>AuthFilter</filter-name>
    <filter-class>com.example.AuthFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>AuthFilter</filter-name>
    <url-pattern>/student/*</url-pattern>
    <url-pattern>/teacher/*</url-pattern>
</filter-mapping>

四、密码重置漏洞

1. 漏洞位置

update_student_security servlet

String id = request.getParameter("id");
String email = request.getParameter("email");
String password = request.getParameter("password");
try {
    studentD.updateStudentSecurity(id, email, password);

2. 漏洞利用

直接访问URL修改任意用户密码:

http://localhost:8081/web/update_student_security?id=20162430646&email=&password=123456

3. 修复方案

  1. 检查当前用户是否有权修改目标账号
  2. 强制验证原密码

修改后的代码:

String currentId = ((Student)session.getAttribute("info")).getId();
String id = request.getParameter("id");

if(!currentId.equals(id)) {
    throw new SecurityException("无权修改其他用户密码");
}

// 继续执行修改逻辑

五、验证码重用漏洞

1. 漏洞位置

check_register servlet

String randStr = (String) session.getAttribute("randStr");
if (!code.equals(randStr)) {
    out.print("<script>alert(\"验证码错误!\");location.href = \"register.jsp\";</script>");
} else {
    // 验证通过后未清除验证码
}

2. 漏洞危害

攻击者可重复使用同一验证码进行注册。

3. 修复方案

验证通过后立即清除session中的验证码:

if (!code.equals(randStr)) {
    // 错误处理
} else {
    session.removeAttribute("randStr"); // 清除验证码
    // 继续注册流程
}

六、目录穿越漏洞

1. 漏洞位置

upload_studentImg servlet

String id = rq.getParameter("id");
File smartFile = smartUpload.getFiles().getFile(0);
smartFile.saveAs("/userImg/"+id+".jpeg");

2. 漏洞利用

通过构造恶意id参数实现目录穿越:

id=../../../path/to/sensitive/file

3. 修复方案

  1. 校验id参数格式
  2. 规范化路径
// 校验id是否为数字
if(!id.matches("\\d+")) {
    throw new IllegalArgumentException("非法ID格式");
}

// 使用Paths规范化路径
Path destination = Paths.get("/userImg").resolve(id + ".jpeg").normalize();

// 确保路径仍在允许的目录内
if(!destination.startsWith("/userImg")) {
    throw new SecurityException("非法文件路径");
}

smartFile.saveAs(destination.toString());

七、XSS漏洞

1. 漏洞位置

多处JSP页面直接输出用户输入:

<td><%=stu.getId()%></td>
<input value="<%=stu.getDatabase()%>" name="database">

2. 漏洞危害

攻击者可注入恶意脚本:

"><script>alert(1)</script><"

3. 修复方案

  1. 使用JSTL的c:out标签
  2. 或使用HTML编码函数

方案一:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<td><c:out value="${stu.id}"/></td>

方案二:

<td><%=HtmlEncoder.encode(stu.getId())%></td>

其中HtmlEncoder实现:

public class HtmlEncoder {
    public static String encode(String input) {
        if(input == null) return "";
        return input.replace("&", "&amp;")
                   .replace("<", "&lt;")
                   .replace(">", "&gt;")
                   .replace("\"", "&quot;")
                   .replace("'", "&#39;");
    }
}

八、安全开发建议

  1. 输入验证:对所有用户输入进行严格验证
  2. 参数化查询:始终使用PreparedStatement
  3. 最小权限原则:数据库连接使用最低必要权限
  4. 输出编码:所有动态内容输出前进行编码
  5. 会话管理:合理设置session超时时间
  6. 错误处理:避免暴露系统敏感信息的错误消息
  7. 安全框架:考虑使用Spring Security等安全框架
  8. 定期审计:建立代码审计机制,定期检查安全漏洞

九、总结

StudentManager系统存在SQL注入、越权访问、密码重置、验证码重用、目录穿越和XSS等多类漏洞,主要原因是缺乏对用户输入的有效验证和不安全的编码实践。通过实施参数化查询、输入验证、输出编码和权限控制等措施,可显著提升系统安全性。

Java代码审计实战:StudentManager系统漏洞分析与修复指南 一、系统概述 StudentManager是一个基于Java Web的学生管理系统,使用Servlet+JSP架构,存在多处严重安全漏洞。本指南将详细分析这些漏洞的原理、危害及修复方案。 二、SQL注入漏洞 1. 漏洞位置与原理 系统在多个DAO类中直接拼接SQL语句,未使用预编译: StudentD.java TeacherD.java 2. 漏洞利用方式 登录处注入Payload: 3. 影响范围 StudentD类中的方法: checkAccount findWithId findWithName deleteStudent TeacherD类中的方法: checkAccount findWithId 4. 修复方案 使用PreparedStatement进行参数化查询: 三、越权访问漏洞 1. 漏洞位置 在main.jsp页面中仅简单获取session信息,未进行权限验证: student/main.jsp teacher/main.jsp 2. 漏洞危害 攻击者无需登录即可直接访问敏感页面,虽然会报500错误,但仍暴露系统结构信息。 3. 修复方案 添加权限验证过滤器: 在web.xml中配置过滤器: 四、密码重置漏洞 1. 漏洞位置 update_ student_ security servlet 2. 漏洞利用 直接访问URL修改任意用户密码: 3. 修复方案 检查当前用户是否有权修改目标账号 强制验证原密码 修改后的代码: 五、验证码重用漏洞 1. 漏洞位置 check_ register servlet 2. 漏洞危害 攻击者可重复使用同一验证码进行注册。 3. 修复方案 验证通过后立即清除session中的验证码: 六、目录穿越漏洞 1. 漏洞位置 upload_ studentImg servlet 2. 漏洞利用 通过构造恶意id参数实现目录穿越: 3. 修复方案 校验id参数格式 规范化路径 七、XSS漏洞 1. 漏洞位置 多处JSP页面直接输出用户输入: 2. 漏洞危害 攻击者可注入恶意脚本: 3. 修复方案 使用JSTL的c:out标签 或使用HTML编码函数 方案一: 方案二: 其中HtmlEncoder实现: 八、安全开发建议 输入验证 :对所有用户输入进行严格验证 参数化查询 :始终使用PreparedStatement 最小权限原则 :数据库连接使用最低必要权限 输出编码 :所有动态内容输出前进行编码 会话管理 :合理设置session超时时间 错误处理 :避免暴露系统敏感信息的错误消息 安全框架 :考虑使用Spring Security等安全框架 定期审计 :建立代码审计机制,定期检查安全漏洞 九、总结 StudentManager系统存在SQL注入、越权访问、密码重置、验证码重用、目录穿越和XSS等多类漏洞,主要原因是缺乏对用户输入的有效验证和不安全的编码实践。通过实施参数化查询、输入验证、输出编码和权限控制等措施,可显著提升系统安全性。