JAVA代码审计之鉴权逻辑错误审计小记
字数 1817 2025-08-30 06:50:11

JAVA代码审计之鉴权逻辑错误审计教学文档

1. 背景介绍

在MyBlog系统的代码审计过程中,发现该系统用户分为两类:

  • 管理员(admin):负责后台文件内容编辑、发布及系统管理配置
  • 普通用户:作为外部访客浏览博客内容、发表评论

2. 初始审计发现

审计初期发现以下特点:

  1. 后端SQL语句采用动态方式组建
  2. 前端可控入参在后端进行了预编译处理
  3. 部分入参限定为INT类型,基本排除了SQL注入可能性

3. 鉴权机制分析

3.1 鉴权方式识别

系统未采用以下常见鉴权方式:

  • 基于角色的访问控制(RBAC):无类似@hasRole("admin")的权限注解
  • 基于属性的访问控制(ABAC):系统仅有一个管理员,不适用
  • Shiro框架:项目未引入Shiro组件

3.2 实际鉴权实现

系统采用拦截器(Interceptor)实现鉴权,关键文件:

  • WebMvcConfig:配置拦截器
  • BaseInterceptor:实现具体拦截逻辑

3.3 关键鉴权流程

BaseInterceptorpreHandle方法中实现主要鉴权逻辑:

  1. 获取请求信息

    String uri = request.getRequestURI();  // 获取URL请求路径
    String ua = request.getHeader("USER_AGENT");  // 获取User-Agent
    String ip = IPKit.getIpAddrByRequest(request);  // 获取请求IP
    
  2. 用户身份验证

    User user = TaleUtils.getLoginUser(request);  // 从session获取用户信息
    if (user == null) {
        Integer uid = TaleUtils.getCookieUid(request);  // 从cookie获取userid
        if (uid != null) {
            // 根据uid查询用户并生成session
        }
    }
    
  3. 权限检查

    if (uri.startsWith("/admin") && !uri.startsWith("/admin/login") && user == null) {
        response.sendRedirect("/admin/login");  // 未登录访问后台则重定向
        return false;
    }
    
  4. CSRF防护

    String csrf_token = UUID.UU64();
    request.setAttribute("_csrf_token", csrf_token);
    request.getSession().setAttribute("_csrf_token", csrf_token);
    

4. 鉴权逻辑漏洞

4.1 漏洞原理

漏洞源于以下两个关键点:

  1. 路径匹配方式

    • 使用request.getRequestURI()获取请求路径
    • 仅简单检查路径是否以/admin开头
  2. Tomcat的URL解析特性

    • Tomcat会对URL进行标准化处理:
      • 删除连续的/只保留一个
      • 删除/./
      • /../进行跨目录拼接处理

4.2 漏洞利用

通过构造特殊URL绕过鉴权:

  1. 正常访问路径

    • /admin/article/delete:需要管理员权限
  2. 绕过方式

    • 构造路径:/admin/login/../article/delete
    • Tomcat解析后会标准化为:/admin/article/delete
    • 但拦截器检查时看到的是/admin/login/..开头,绕过鉴权

4.3 漏洞验证

  1. 正常请求

    • 无权限访问/admin/article/delete会被重定向到登录页
  2. 恶意请求

    • 访问/admin/login/../article/delete
    • 虽然返回success: false,但实际删除操作执行成功

5. 相关技术背景

5.1 Tomcat的URL解析方法

HTTPServletRequest常用方法:

方法 描述
getRequestURL() 返回完整路径
getRequestURI() 返回除去Host部分的路径
getContextPath() 返回工程名部分
getServletPath() 返回除去Host和工程名部分的路径
getPathInfo() 返回传递到Servlet的额外路径信息

5.2 URL标准化处理

Tomcat对URL的处理:

  1. 删除连续的/(如////
  2. 删除/./
  3. 处理/../进行跨目录拼接
  4. /;xxx/等特殊字符有特殊处理

6. 防御建议

  1. 改进鉴权方式

    • 使用成熟的权限框架如Shiro或Spring Security
    • 实现基于角色的细粒度权限控制
  2. 路径检查改进

    // 使用规范化后的路径进行检查
    String normalizedUri = request.getRequestURI().replaceAll("/+", "/");
    if (normalizedUri.startsWith("/admin") && ...) {
        // 鉴权逻辑
    }
    
  3. 多重验证机制

    • 结合路径检查和角色/权限注解
    • 对敏感操作进行二次验证
  4. 日志监控

    • 记录所有管理操作
    • 监控异常的路径访问模式

7. 类似案例

  1. F5 BIG-IP漏洞

    • Tomcat和Nginx解析差异导致的认证绕过和RCE
    • 原理与本案例类似,都是解析差异导致的安全问题
  2. 其他Web容器漏洞

    • 不同Web服务器对URL解析的差异
    • 编码/解码处理不一致导致的安全问题

8. 审计要点总结

  1. 鉴权机制审计

    • 识别系统使用的鉴权方式
    • 检查是否采用成熟的权限框架
    • 验证自定义鉴权逻辑的严谨性
  2. 路径处理审计

    • 检查URL获取和处理方式
    • 验证路径规范化处理
    • 测试特殊字符和路径遍历的可能性
  3. 容器特性审计

    • 了解部署容器的URL解析特性
    • 测试解析差异可能导致的安全问题
    • 验证多层代理/网关环境下的行为一致性

通过本案例,安全审计人员应重视系统鉴权实现方式与底层容器特性的交互可能带来的安全隐患。

JAVA代码审计之鉴权逻辑错误审计教学文档 1. 背景介绍 在MyBlog系统的代码审计过程中,发现该系统用户分为两类: 管理员(admin):负责后台文件内容编辑、发布及系统管理配置 普通用户:作为外部访客浏览博客内容、发表评论 2. 初始审计发现 审计初期发现以下特点: 后端SQL语句采用动态方式组建 前端可控入参在后端进行了预编译处理 部分入参限定为INT类型,基本排除了SQL注入可能性 3. 鉴权机制分析 3.1 鉴权方式识别 系统未采用以下常见鉴权方式: 基于角色的访问控制(RBAC):无类似 @hasRole("admin") 的权限注解 基于属性的访问控制(ABAC):系统仅有一个管理员,不适用 Shiro框架:项目未引入Shiro组件 3.2 实际鉴权实现 系统采用拦截器(Interceptor)实现鉴权,关键文件: WebMvcConfig :配置拦截器 BaseInterceptor :实现具体拦截逻辑 3.3 关键鉴权流程 在 BaseInterceptor 的 preHandle 方法中实现主要鉴权逻辑: 获取请求信息 : 用户身份验证 : 权限检查 : CSRF防护 : 4. 鉴权逻辑漏洞 4.1 漏洞原理 漏洞源于以下两个关键点: 路径匹配方式 : 使用 request.getRequestURI() 获取请求路径 仅简单检查路径是否以 /admin 开头 Tomcat的URL解析特性 : Tomcat会对URL进行标准化处理: 删除连续的 / 只保留一个 删除 /./ 对 /../ 进行跨目录拼接处理 4.2 漏洞利用 通过构造特殊URL绕过鉴权: 正常访问路径 : /admin/article/delete :需要管理员权限 绕过方式 : 构造路径: /admin/login/../article/delete Tomcat解析后会标准化为: /admin/article/delete 但拦截器检查时看到的是 /admin/login/.. 开头,绕过鉴权 4.3 漏洞验证 正常请求 : 无权限访问 /admin/article/delete 会被重定向到登录页 恶意请求 : 访问 /admin/login/../article/delete 虽然返回 success: false ,但实际删除操作执行成功 5. 相关技术背景 5.1 Tomcat的URL解析方法 HTTPServletRequest常用方法: | 方法 | 描述 | |------|------| | getRequestURL() | 返回完整路径 | | getRequestURI() | 返回除去Host部分的路径 | | getContextPath() | 返回工程名部分 | | getServletPath() | 返回除去Host和工程名部分的路径 | | getPathInfo() | 返回传递到Servlet的额外路径信息 | 5.2 URL标准化处理 Tomcat对URL的处理: 删除连续的 / (如 /// → / ) 删除 /./ 处理 /../ 进行跨目录拼接 对 /;xxx/ 等特殊字符有特殊处理 6. 防御建议 改进鉴权方式 : 使用成熟的权限框架如Shiro或Spring Security 实现基于角色的细粒度权限控制 路径检查改进 : 多重验证机制 : 结合路径检查和角色/权限注解 对敏感操作进行二次验证 日志监控 : 记录所有管理操作 监控异常的路径访问模式 7. 类似案例 F5 BIG-IP漏洞 : Tomcat和Nginx解析差异导致的认证绕过和RCE 原理与本案例类似,都是解析差异导致的安全问题 其他Web容器漏洞 : 不同Web服务器对URL解析的差异 编码/解码处理不一致导致的安全问题 8. 审计要点总结 鉴权机制审计 : 识别系统使用的鉴权方式 检查是否采用成熟的权限框架 验证自定义鉴权逻辑的严谨性 路径处理审计 : 检查URL获取和处理方式 验证路径规范化处理 测试特殊字符和路径遍历的可能性 容器特性审计 : 了解部署容器的URL解析特性 测试解析差异可能导致的安全问题 验证多层代理/网关环境下的行为一致性 通过本案例,安全审计人员应重视系统鉴权实现方式与底层容器特性的交互可能带来的安全隐患。