当前位置: 首页 > news >正文

RuoYi issue1: Role Menu Permission Overwrite

Vulnerability call chain

1.1 Summary

RuoYi has a missing authorization vulnerability: Role Menu Permission Overwrite. 角色被授予操作者本不具备的菜单/接口权限;若该角色已分配给用户,权限会在 Shiro 重新加载后生效。

  • Attack precondition: 非超级管理员拥有 system:role:addsystem:role:edit
  • Affected authorization property: ``sys_role_menu.role_id, sys_role_menu.menu_id, SysRole.menuIds
  • Security impact: 角色被授予操作者本不具备的菜单/接口权限;若该角色已分配给用户,权限会在 Shiro 重新加载后生效。

1.2 Exploit path

直接 POST /system/role/add/system/role/edit,提交当前用户不可见或不可授权的 menuIds

1.3 Key code evidence

  1. ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java

Evidence location: https://github.com/yangzongzhuan/RuoYi/blob/master/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java#L95

   92      @PostMapping("/add")93      @ResponseBody94      public AjaxResult addSave(@Validated SysRole role)95      {96          if (!roleService.checkRoleNameUnique(role))97          {98              return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");99          }100          else if (!roleService.checkRoleKeyUnique(role))101          {102              return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");103          }104          role.setCreateBy(getLoginName());105          AuthorizationUtils.clearAllCachedAuthorizationInfo();106          return toAjax(roleService.insertRole(role));107  108      }109  110      /**111       * 修改角色112       */113      @RequiresPermissions("system:role:edit")114      @GetMapping("/edit/{roleId}")
  1. ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java

Evidence location: https://github.com/yangzongzhuan/RuoYi/blob/master/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java#L198

  195       * @param role 角色信息196       * @return 结果197       */198      @Override199      @Transactional200      public int updateRole(SysRole role)201      {202          // 修改角色信息203          roleMapper.updateRole(role);204          // 删除角色与菜单关联205          roleMenuMapper.deleteRoleMenuByRoleId(role.getRoleId());206          return insertRoleMenu(role);207      }
  1. ruoyi-system/target/classes/mapper/system/SysRoleMenuMapper.xml

Evidence location: https://github.com/yangzongzhuan/RuoYi/blob/master/ruoyi-system/target/classes/mapper/system/SysRoleMenuMapper.xml#L27

   24          </foreach> 25   	</delete>26  	27  	<insert id="batchRoleMenu">28  		insert into sys_role_menu(role_id, menu_id) values29  		<foreach item="item" index="index" collection="list" separator=",">30  			(#{item.roleId},#{item.menuId})31  		</foreach>32  	</insert>33  	34  </mapper> 
  1. ruoyi-system/target/classes/mapper/system/SysMenuMapper.xml

Evidence location: https://github.com/yangzongzhuan/RuoYi/blob/master/ruoyi-system/target/classes/mapper/system/SysMenuMapper.xml#L64

   61  		order by m.parent_id, m.order_num62  	</select>63  64  	<select id="selectPermsByUserId" parameterType="Long" resultType="String">65  		select distinct m.perms66  		from sys_menu m67  			 left join sys_role_menu rm on m.menu_id = rm.menu_id68  			 left join sys_user_role ur on rm.role_id = ur.role_id69  			 left join sys_role r on r.role_id = ur.role_id70  		where m.visible = '0' and r.status = '0' and ur.user_id = #{userId}71  	</select>72  73  	<select id="selectPermsByRoleId" parameterType="Long" resultType="String">

3. Root Cause Analysis

Root Cause 1: Missing server-side authorization on the vulnerable operation.

The endpoint accepts user-controlled authorization-sensitive identifiers or fields, but the write/read path does not prove that the current caller may operate on the target object.

Root Cause 2: Missing object-scope or grant-bound validation.

The implementation relies on endpoint access, UI filtering, or object existence checks instead of enforcing target ownership, tenant boundary, role ceiling, or grantable-resource constraints at the service layer.

保存角色菜单前校验每个 menuId 属于 menuService.selectMenuAll(currentUserId),或仅允许超级管理员写 sys_role_menu

5. Verification after fix

  • Unauthorized callers receive HTTP 403 or equivalent rejection.
  • Out-of-scope target identifiers are rejected before database writes or sensitive reads.
  • Role, permission, tenant, organization, ownership, or grant-bound ceilings are enforced server-side.
  • Direct HTTP requests are rejected even when front-end controls are hidden.
http://www.jsqmd.com/news/1035881/

相关文章:

  • Honey Select 2汉化去码补丁:5分钟打造完美游戏体验
  • 2026西藏焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • 基于KEA128的无感BLDC驱动:从硬件设计到反电动势过零检测算法实践
  • Appium复杂手势模拟:从W3C Actions到源码级调试实战
  • DSpace issue3: Registration Token Path Allows Arbitrary netid Binding
  • 国内亚克力定制主流厂家盘点 核心能力横向对比 - 起跑123
  • 2026忻州焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • JEEWMS issue1: `saveUser` 可重建用户角色和组织绑定
  • 2026西宁焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • 2026年移动拖车发电机组工厂推荐:静音节能与应急供电的实力之选 - 品牌发掘
  • 2026 AIGC 全球挑战赛收官:131 组作品角逐,为北京数字经济发展注入新动能!
  • B站缓存视频容器格式转换技术实现:m4s-converter架构解析与应用指南
  • 模型量化:从 FP16 到 INT4,怎么平衡精度和速度
  • 如何在5分钟内完成专业级虚拟背景设置:OBS背景移除插件终极指南
  • ZigBee网络配置实战:从ZPS工具到休眠设备通信避坑
  • 2026实力之选:泰州阳光发电设备有限公司——沃尔沃发电机组供应商的可靠动力之源 - 品牌发掘
  • 吴忠市空调维修/中央空调维修|本地避坑指南,满分五星平台|欧米到家首选 - 欧米到家
  • 实战指南:3步部署Qwen2-7B-Instruct,解锁企业级AI助手核心功能
  • 2026宿州焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • 2026烟台焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • 音频表示学习中的组合性评估与实践
  • RuoYi issue2: Role Data Scope Escalation
  • 终极指南:5分钟快速掌握OBS背景移除插件的完整教程
  • 终极指南:如何让旧Mac免费升级到最新macOS系统(OpenCore Legacy Patcher完整教程)
  • 名表维修渠道乱象调查:亨得利官方发布2026服务渠道识别严正声明 - 亨得利官方维修中心
  • JEEWMS issue2: `updateAuthority` 可改写角色功能权限
  • Linux进程创建实验详解:从fork()原理到实践应用
  • 山南市空调维修/中央空调维修|本地避坑指南,满分五星平台|欧米到家首选 - 欧米到家
  • 2026乌兰察布焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • 如何选择北京企业纠纷律所?2026年6月推荐十大排名评测专业价格注意事项案例 - 品牌推荐