Skip to content

JeecgBoot Tenant Privilege Escalation: GET /sys/sysDepartRole/getDeptRoleList Department Role Query Without Tenant Validation #33

@Hwwg

Description

@Hwwg

JeecgBoot Tenant Privilege Escalation: GET /sys/sysDepartRole/getDeptRoleList Department Role Query Without Tenant Validation

Contributors: huangweigang

1. Impact Scope

2. Vulnerable Endpoint

  • GET /sys/sysDepartRole/getDeptRoleList?departId=...&userId=... (Get Department Role List API)

3. Code Analysis

  • Controller: jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartRoleController.java
    • Route & method:
      • @RequestMapping(value = "/getDeptRoleList", method = RequestMethod.GET)
      • public Result<List<SysDepartRole>> getDeptRoleList(@RequestParam(value = "departId") String departId,@RequestParam(value = "userId") String userId)
    • Key code (lines 183–191):
      • Result<List<SysDepartRole>> result = new Result<>();
      • //Query roles in the selected department
      • List<SysDepartRole> deptRoleList = sysDepartRoleService.list(new LambdaQueryWrapper<SysDepartRole>().eq(SysDepartRole::getDepartId,departId));
      • result.setSuccess(true);
      • result.setResult(deptRoleList);
      • return result;
  • Problem points:
    • The endpoint directly uses the departId parameter to query the department role list without any tenant ownership validation
    • The userId parameter, although passed in, is not used and cannot serve as permission verification
    • Attackers can obtain all role configurations of any department using arbitrary department IDs
    • Missing tenant isolation and permission verification mechanisms

4. Reproduction

-- Prerequisites

  • Attacker has a valid login session
  • Attacker knows or can enumerate the target tenant's department ID
  • Can construct arbitrary userId parameter (this parameter is not actually used)

-- Steps (Cross-tenant Role Information Disclosure)

  • Using attacker account (Tenant A):
    • curl -X GET -H "Authorization: Bearer <attacker_token>" "http://<host>/jeecgboot/sys/sysDepartRole/getDeptRoleList?departId=<victim_dept_id>&userId=dummy"
  • Observation: API returns 200 OK, returns all roles list under Tenant B's department
  • Verification:
    • Use Tenant B's legitimate account to call the same endpoint and compare the returned data
    • Database query confirms the returned role data belongs to another tenant

5. Impact

  • Cross-tenant information disclosure
    • Attackers can obtain any tenant's department role information, including role names, role codes, descriptions, etc.
  • Permission system exposure
    • Exposes other tenants' permission architecture design, helping attackers understand the target system's permission model
  • Organizational structure information disclosure
    • Role information can reveal the organization's department function division and management hierarchy
  • Provides intelligence for further attacks
    • After understanding target tenant's permission configuration, targeted privilege escalation attacks can be conducted

6. Remediation

  • Add tenant ownership validation
    • Verify whether the department belongs to the current tenant before querying:
      • SysDepart depart = sysDepartService.getById(departId);
      • LoginUser currentUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
      • if(depart == null || !depart.getTenantId().equals(currentUser.getTenantId())) {
      • return Result.error("Unauthorized to access this department role information");
      • }
  • Force tenant filtering
    • Add tenant ID filtering condition when querying roles to ensure only current tenant's data is returned
  • Use userId parameter for permission verification
    • Verify whether the current user has permission to view the specified department's role information
  • Database-level tenant isolation
    • Configure MyBatis-Plus multi-tenancy plugin to automatically add tenant ID filtering in SQL
  • Audit logging
    • Record all department role query operations, especially cross-tenant access attempts

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions