Submit #711773: JeecgBoot 3.9.0 Improper Control of Resource Identifiersinfo

TitleJeecgBoot 3.9.0 Improper Control of Resource Identifiers
Description# JeecgBoot Tenant Privilege Escalation: GET /sys/sysDepartRole/getDeptRoleByUserId User Department Role Query Without Tenant Validation ## Contributors: huangweigang ### 1. Impact Scope - JeecgBoot (latest) - https://github.com/jeecgboot/jeecg-boot ### 2. Vulnerable Endpoint - GET `/sys/sysDepartRole/getDeptRoleByUserId?userId=...&departId=...` (Get User's Assigned Department Roles 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 = "/getDeptRoleByUserId", method = RequestMethod.GET)` - `public Result<List<SysDepartRoleUser>> getDeptRoleByUserId(@RequestParam(value = "userId") String userId,@RequestParam(value = "departId") String departId)` - Key code (lines 217–231): - `Result<List<SysDepartRoleUser>> result = new Result<>();` - `//Query department roles` - `List<SysDepartRole> roleList = sysDepartRoleService.list(new QueryWrapper<SysDepartRole>().eq("depart_id",departId));` - `List<String> roleIds = roleList.stream().map(SysDepartRole::getId).collect(Collectors.toList());` - `//Query authorized roles based on role id and user id` - `List<SysDepartRoleUser> roleUserList = null;` - `if(roleIds!=null && roleIds.size()>0){` - ` roleUserList = departRoleUserService.list(new QueryWrapper<SysDepartRoleUser>().eq("user_id",userId).in("drole_id",roleIds));` - `}` - `result.setSuccess(true);` - `result.setResult(roleUserList);` - `return result;` - Problem points: - The endpoint directly uses `departId` to query department roles without verifying the department's tenant ownership - Directly uses `userId` to query user role authorizations without verifying whether the user belongs to the current tenant - Attackers can query the user department role authorization status of any tenant - May leak cross-tenant user permission configuration information ### 4. Reproduction -- Prerequisites - Attacker has a valid login session - Attacker knows or can enumerate the target tenant's user ID and department ID - System has multi-tenancy mode enabled -- Steps (Cross-tenant User Permission Information Disclosure) - Using attacker account (Tenant A): - `curl -X GET -H "Authorization: Bearer <attacker_token>" "http://<host>/jeecgboot/sys/sysDepartRole/getDeptRoleByUserId?userId=<victim_user_id>&departId=<victim_dept_id>"` - Observation: API returns 200 OK, returns the target user's role authorization list in the specified department - Verification: - Use Tenant B's administrator account to query the same user's roles and confirm data consistency - Database query sys_depart_role_user table to confirm the returned authorization relationship belongs to another tenant ### 5. Impact - Cross-tenant user permission information disclosure - Attackers can obtain other tenant users' department role authorization information - Understand the target user's permission level and functional scope within the organization - Permission system analysis - By querying different users' role authorizations in bulk, complete organizational permission architecture diagrams can be drawn - Personnel information disclosure - Confirm specific users' department affiliations and role responsibilities within the organization - Provides intelligence for privilege escalation attacks - Identify high-privilege users, providing targets for subsequent targeted attacks ### 6. Remediation - Department tenant ownership validation - Verify whether the department corresponding to `departId` belongs to the current tenant: - `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 data");` - `}` - User tenant ownership validation - Verify whether the user corresponding to `userId` belongs to the current tenant: - `SysUser user = sysUserService.getById(userId);` - `if(user == null || !sysUserTenantService.userBelongsToTenant(userId, currentUser.getTenantId())) {` - ` return Result.error("Unauthorized to query this user information");` - `}` - Force tenant filtering - Add tenant ID filtering conditions in all database queries - Least privilege principle - Restrict ordinary users to only query their own role authorizations, only administrators can query other users - Audit logging - Record all user role query operations, especially cross-tenant access attempts
Source⚠️ https://github.com/Hwwg/cve/issues/34
User
 huangweigang (UID 88993)
Submission12/10/2025 13:04 (4 months ago)
Moderation12/27/2025 10:01 (17 days later)
StatusAccepted
VulDB entry338499 [JeecgBoot up to 3.9.0 getDeptRoleByUserId departId information disclosure]
Points20

Interested in the pricing of exploits?

See the underground prices here!