| Title | yangzongzhuan RuoYi-Vue 3.9.2 Improper Privilege Management |
|---|
| Description | A vulnerability was found in yangzongzhuan RuoYi-Vue up to 3.9.2. It has been declared as critical. This vulnerability affects the function getMenuPermission of the file SysPermissionService.java and the functions insertMenu and updateMenu of the file SysMenuServiceImpl.java. The manipulation of the argument perms with the input *:*:* leads to improper privilege management. It is possible to launch the attack remotely. The exploit has been disclosed to the public and may be used.
CLASS
Improper Privilege Management
CWE-269 (Improper Privilege Management), CWE-863 (Incorrect Authorization)
CVSS 3.1: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H (8.8 HIGH)
AFFECTED COMPONENT
File: SysMenuServiceImpl.java (functions insertMenu and updateMenu)
File: SysPermissionService.java (function getMenuPermission)
File: PermissionService.java (function hasPermissions)
Parameter: perms (menu permission identifier)
ROOT CAUSE
1. Constants.java:76 declares ALL_PERMISSION = "*:*:*". SysPermissionService.getMenuPermission() adds this wildcard ONLY inside the if (user.isAdmin()) branch, so the framework invariant is that the wildcard belongs solely to the built-in super administrator (userId == 1).
2. SysMenuServiceImpl.insertMenu() and updateMenu() perform no validation on the perms field. SysMenu.getPerms() carries only a Size(max = 100) length constraint. The menu table therefore becomes an unvalidated second producer of the reserved wildcard.
3. PermissionService.hasPermissions() trusts the value blindly: it returns true whenever the permission set contains "*:*:*", with no way to distinguish the origin of the wildcard.
PRECONDITIONS
An account that has been delegated menu management and role management permissions (system:menu:add, system:menu:edit and system:role:edit). Verified with data_scope 1, 2, 3 and 4. Only data_scope 5 fails because checkRoleDataScope then rejects editing one's own role.
PROOF OF CONCEPT
Step 1: POST /system/menu with the perms argument set to "*:*:*" returns {"msg":"操作成功","code":200}
Step 2: PUT /system/role granting that menu to the attacker's own role returns {"msg":"操作成功","code":200}
Step 3: After re-login, GET /getInfo returns {"permissions":["*:*:*"],"roles":["common"],"user":{"userId":2,"admin":false}}
IMPACT
The account obtains all function-level permissions while still reporting admin = false and roles = ["common"]. Measured access includes login records with source IP, online users, operation logs, system parameters, server metrics and the code generator. Write permissions for user, role and department management are granted as well.
Boundary: the wildcard does NOT equal full super-administrator takeover. Operations on the built-in super-admin account are still refused, because checkUserAllowed() and checkUserDataScope() rely on isAdmin() (hard-coded userId == 1) and DataScope rather than on the permission set.
NEGATIVE CONTROL
Same account and same environment with the menu perms value changed to "probe:only:read": the permission set becomes [probe:only:read] and all six endpoints above return 403. The single variable is the perms value, therefore the escalation is caused by the reserved wildcard and not by the menu and role management permissions themselves.
SUGGESTED FIX (verified effective)
Reject the reserved wildcard where the menu entry is written, in SysMenuServiceImpl.insertMenu() and updateMenu():
if (StringUtils.isNotEmpty(perms) && Constants.ALL_PERMISSION.equals(perms.trim())) {
throw new ServiceException("reserved permission identifier not allowed");
}
After patching, step 1 returns an error and the number of accessible endpoints drops from 6/6 to 0/6, while ordinary perms values are still accepted, so the fix does not break legitimate menu creation.
OTHER AFFECTED PROJECTS (same root cause, confirmed by reading source)
RuoYi-Cloud 3.6.8: SysPermissionServiceImpl.getMenuPermission() is line-for-line identical.
RuoYi-Vue-Plus 5.X: if (LoginHelper.isSuperAdmin(userId)) perms.add("*:*:*") else perms.addAll(...), and SysMenuController.add() only calls checkMenuNameUnique().
PUBLIC DISCLOSURE
https://github.com/yangzongzhuan/RuoYi-Vue/issues/206 |
|---|
| Source | ⚠️ https://github.com/yangzongzhuan/RuoYi-Vue/issues/206 |
|---|
| User | OMrYangO (UID 102064) |
|---|
| Submission | 10/11/2026 16:47 (24 days ago) |
|---|
| Moderation | 11/04/2026 15:33 (24 days later) |
|---|
| Status | Accepted |
|---|
| VulDB entry | 431084 [yangzongzhuan RuoYi-Vue up to 3.9.2 Permission Service SysPermissionService.java SysPermissionService.getMenuPermission perms privileges management] |
|---|
| Points | 20 |
|---|