Skip to content

JeecgBoot Tenant Privilege Escalation: GET /sys/permission/queryDepartPermission Department Authorization Menu Query Without Tenant Validation #38

@Hwwg

Description

@Hwwg

JeecgBoot Tenant Privilege Escalation: GET /sys/permission/queryDepartPermission Department Authorization Menu Query Without Tenant Validation

Contributors: huangweigang

1. Impact Scope

2. Vulnerable Endpoint

  • GET /sys/permission/queryDepartPermission?departId=... (Query Department Authorization Menu API)

3. Code Analysis

  • Controller: jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPermissionController.java
    • Route & method:
      • @RequestMapping(value = "/queryDepartPermission", method = RequestMethod.GET)
      • public Result<List<String>> queryDepartPermission(@RequestParam(name = "departId", required = true) String departId)
    • Key code (lines 1000–1011):
      • Result<List<String>> result = new Result<>();
      • try {
      • List<SysDepartPermission> list = sysDepartPermissionService.list(new QueryWrapper<SysDepartPermission>().lambda().eq(SysDepartPermission::getDepartId, departId));
      • result.setResult(list.stream().map(sysDepartPermission -> String.valueOf(sysDepartPermission.getPermissionId())).collect(Collectors.toList()));
      • result.setSuccess(true);
      • } catch (Exception e) {
      • log.error(e.getMessage(), e);
      • }
      • return result;
  • Problem points:
    • The endpoint directly uses the departId parameter to query the department's authorization menu list
    • Does not verify whether the department belongs to the current tenant
    • Returns a list of permission IDs, exposing the department's complete menu authorization configuration
    • Attackers can obtain menu permission configurations of all tenants by enumerating department IDs

4. Reproduction

-- Prerequisites

  • Attacker has a valid login session
  • Attacker knows or can enumerate the target tenant's department ID
  • System has department-level menu permissions configured

-- Steps (Cross-tenant Menu Permission Configuration Disclosure)

  • Using attacker account (Tenant A):
    • curl -X GET -H "Authorization: Bearer <attacker_token>" "http://<host>/jeecgboot/sys/permission/queryDepartPermission?departId=<victim_dept_id>"
  • Observation: API returns 200 OK, returns the list of authorized permission IDs for the target department, for example:
    • ["1", "2", "3", "100", "200", ...]
  • Verification:
    • Use Tenant B's administrator account to query the same department's permission configuration
    • Query sys_permission table based on permission IDs to confirm corresponding menu functions
    • Confirm the returned permission configuration belongs to another tenant

5. Impact

  • Menu permission configuration disclosure
    • Attackers can obtain any tenant's department menu authorization status
    • Understand which functional modules and menus different departments can access
  • Functional module architecture exposure
    • Permission ID lists can be reverse-engineered to infer the system's functional module divisions
    • Combined with permission table, complete system functional architecture can be mapped
  • Permission system analysis
    • By querying multiple departments' permission configurations, complete organizational permission allocation diagrams can be drawn
  • Provides intelligence for subsequent attacks
    • Understand which departments have access to sensitive functions
    • Identify high-privilege departments, select targets for privilege escalation attacks

6. Remediation

  • Department 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 permission configuration");
      • }
  • Force tenant filtering
    • When querying department permissions, ensure the department belongs to the current tenant through JOIN or subquery
  • Permission level control
    • Restrict only department administrators or system administrators to query department permission configurations
    • Ordinary users can only query permissions of their own departments
  • Data desensitization
    • Apply appropriate desensitization to sensitive permission configuration information based on the querier's role
  • Audit logging
    • Record all department permission query operations
    • Pay special attention to cross-tenant access attempts and high-frequency query behaviors

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