Submit #711776: 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/sysDepartPermission/list Department Permission List Query Without Tenant Validation ## Contributors: huangweigang ### 1. Impact Scope - JeecgBoot (latest) - https://github.com/jeecgboot/jeecg-boot ### 2. Vulnerable Endpoint - GET `/sys/sysDepartPermission/list?departId=...&pageNo=1&pageSize=10` (Department Permission Table Paginated List Query API) ### 3. Code Analysis - Controller: `jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartPermissionController.java` - Route & method: - `@GetMapping(value = "/list")` - `public Result<?> queryPageList(SysDepartPermission sysDepartPermission, @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, HttpServletRequest req)` - Key code (lines 75–84): - `QueryWrapper<SysDepartPermission> queryWrapper = QueryGenerator.initQueryWrapper(sysDepartPermission, req.getParameterMap());` - `Page<SysDepartPermission> page = new Page<SysDepartPermission>(pageNo, pageSize);` - `IPage<SysDepartPermission> pageList = sysDepartPermissionService.page(page, queryWrapper);` - `return Result.ok(pageList);` - Problem points: - The endpoint uses `QueryGenerator.initQueryWrapper` to automatically build query conditions, supporting filtering via `departId` parameter - Does not validate tenant ownership of the `departId` parameter - Attackers can query other tenants' department permission configurations by specifying arbitrary department IDs - Completely relies on frontend-provided query parameters, lacking server-side permission verification ### 4. Reproduction -- Prerequisites - Attacker has a valid login session - Attacker knows or can enumerate the target tenant's department ID - System has department-level permission authorization configured -- Steps (Cross-tenant Department Permission Configuration Disclosure) - Using attacker account (Tenant A): - `curl -X GET -H "Authorization: Bearer <attacker_token>" "http://<host>/jeecgboot/sys/sysDepartPermission/list?departId=<victim_dept_id>&pageNo=1&pageSize=100"` - Observation: API returns 200 OK, returns the target department's permission configuration list, including: - Department ID (departId) - Permission ID (permissionId) - Data Rule IDs (dataRuleIds) - Metadata such as creation time - Verification: - Use Tenant B's administrator account to query the same department's permission configuration and confirm data consistency - Database query sys_depart_permission table to confirm data ownership ### 5. Impact - Cross-tenant permission configuration disclosure - Attackers can obtain any tenant's department permission configuration information - Understand which menus and functions are authorized to which departments - Organizational structure and permission system exposure - Permission configuration can be reverse-engineered to infer the organization's department structure and functional divisions - Business functions and modules disclosure - Permission IDs correspond to functional modules, exposing the system's business functional architecture - Provides foundation for privilege escalation attacks - After understanding permission configuration, attackers can specifically search for privilege escalation vulnerabilities ### 6. Remediation - Department tenant ownership validation - When accepting `departId` parameter, verify whether the department belongs to the current tenant: - `if(oConvertUtils.isNotEmpty(sysDepartPermission.getDepartId())) {` - ` SysDepart depart = sysDepartService.getById(sysDepartPermission.getDepartId());` - ` LoginUser currentUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();` - ` if(depart == null || !depart.getTenantId().equals(currentUser.getTenantId())) {` - ` return Result.error("Unauthorized to access this department permission data");` - ` }` - `}` - Force tenant filtering - Forcibly add tenant ID filtering condition in QueryWrapper: - `queryWrapper.eq("tenant_id", TenantContext.getTenant());` - Database-level tenant isolation - Configure MyBatis-Plus multi-tenancy plugin for automatic filtering at SQL level - Parameter whitelist - Restrict allowed query parameter fields to prevent cross-tenant queries via arbitrary fields - Audit logging - Record all department permission query operations, especially focus on cross-tenant access attempts
Source⚠️ https://github.com/Hwwg/cve/issues/37
User
 huangweigang (UID 88993)
Submission12/10/2025 01:11 PM (4 months ago)
Moderation12/27/2025 10:01 AM (17 days later)
StatusAccepted
VulDB entry338502 [JeecgBoot up to 3.9.0 list getParameterMap departId improper authorization]
Points20

Do you want to use VulDB in your project?

Use the official API to access entries easily!