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

RuoYi issue2: Role Data Scope Escalation

Vulnerability call chain

1.1 Summary

RuoYi has a missing authorization vulnerability: Role Data Scope Escalation. 扩大角色数据权限,使拥有该角色的用户后续通过 DataScope 查询到未授权部门数据。

  • Attack precondition: 拥有 system:role:edit,且目标 roleId 能通过 checkRoleDataScope
  • Affected authorization property: ``sys_role.data_scope, sys_role_dept.role_id, sys_role_dept.dept_id, SysRole.deptIds
  • Security impact: 扩大角色数据权限,使拥有该角色的用户后续通过 DataScope 查询到未授权部门数据。

1.2 Exploit path

POST /system/role/authDataScope,提交越权 dataScope=1 或不可见部门 deptIds

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#L165

  162      @Log(title = "角色管理", businessType = BusinessType.UPDATE)163      @PostMapping("/authDataScope")164      @ResponseBody165      public AjaxResult authDataScopeSave(SysRole role)166      {167          roleService.checkRoleAllowed(role);168          roleService.checkRoleDataScope(role.getRoleId());169          role.setUpdateBy(getLoginName());170          if (roleService.authDataScope(role) > 0)171          {172              setSysUser(userService.selectUserById(getUserId()));173              return success();174          }175          return error();176      }177  
  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#L215

  212       * @param role 角色信息213       * @return 结果214       */215      @Override216      @Transactional217      public int authDataScope(SysRole role)218      {219          // 修改角色信息220          roleMapper.updateRole(role);221          // 删除角色与部门关联222          roleDeptMapper.deleteRoleDeptByRoleId(role.getRoleId());223          // 新增角色和部门信息(数据权限)224          return insertRoleDept(role);225      }
  1. ruoyi-system/target/classes/mapper/system/SysRoleMapper.xml

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

   92          </foreach> 93   	</delete>94   	95   	<update id="updateRole" parameterType="SysRole">96   		update sys_role97   		<set>98   			<if test="roleName != null and roleName != ''">role_name = #{roleName},</if>99   			<if test="roleKey != null and roleKey != ''">role_key = #{roleKey},</if>100   			<if test="roleSort != null and roleSort != ''">role_sort = #{roleSort},</if>101   			<if test="dataScope != null and dataScope != ''">data_scope = #{dataScope},</if>102   			<if test="status != null and status != ''">status = #{status},</if>103   			<if test="remark != null">remark = #{remark},</if>104   			<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>105   			update_time = sysdate()106   		</set>107   		where role_id = #{roleId}108  	</update>109   	110   	<insert id="insertRole" parameterType="SysRole" useGeneratedKeys="true" keyProperty="roleId">
  1. ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java

Evidence location: https://github.com/yangzongzhuan/RuoYi/blob/master/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java#L79

   76              }77          }78      }79  80      /**81       * 数据范围过滤82       * 83       * @param joinPoint 切点84       * @param user 用户85       * @param deptAlias 部门别名86       * @param userAlias 用户别名87       * @param permission 权限字符88       */89      public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, String permission)90      {91          StringBuilder sqlString = new StringBuilder();92          List<String> conditions = new ArrayList<String>();93          List<String> scopeCustomIds = new ArrayList<String>();94          user.getRoles().forEach(role -> {95              if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL) && (StringUtils.isEmpty(permission) || StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))))96              {97                  scopeCustomIds.add(Convert.toStr(role.getRoleId()));98              }99          });100  101          for (SysRole role : user.getRoles())102          {103              String dataScope = role.getDataScope();104              if (conditions.contains(dataScope) || StringUtils.equals(role.getStatus(), UserConstants.ROLE_DISABLE))105              {106                  continue;107              }108              if (StringUtils.isNotEmpty(permission) && !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))109              {110                  continue;111              }112              if (DATA_SCOPE_ALL.equals(dataScope))113              {114                  sqlString = new StringBuilder();115                  conditions.add(dataScope);
  1. deptService.c

Evidence location: https://github.com/yangzongzhuan/RuoYi/blob/master/deptService.c

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.

禁止非 admin 设置全部数据权限;对每个 deptId 调用 deptService.checkDeptDataScope(deptId);校验新 dataScope 不超过操作者自身范围。

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/1035859/

相关文章:

  • 终极指南:5分钟快速掌握OBS背景移除插件的完整教程
  • 终极指南:如何让旧Mac免费升级到最新macOS系统(OpenCore Legacy Patcher完整教程)
  • 名表维修渠道乱象调查:亨得利官方发布2026服务渠道识别严正声明 - 亨得利官方维修中心
  • JEEWMS issue2: `updateAuthority` 可改写角色功能权限
  • Linux进程创建实验详解:从fork()原理到实践应用
  • 山南市空调维修/中央空调维修|本地避坑指南,满分五星平台|欧米到家首选 - 欧米到家
  • 2026乌兰察布焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • 如何选择北京企业纠纷律所?2026年6月推荐十大排名评测专业价格注意事项案例 - 品牌推荐
  • 2026新疆焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • json模块:序列化反序列化、中文乱码、json文件读写实战
  • 如何快速获取网盘直链:2025年最新下载方案终极指南
  • 2026年 泰州水泵发电机组实力厂家:稳定高效与节能降噪技术解析及选购指南 - 品牌发掘
  • RuoYi issue3: Unauthorized Role Assignment To Users
  • 终极Windows热键冲突检测指南:Hotkey Detective让键盘快捷键重获新生
  • 2026西双版纳焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • 2026山西焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • 2026绥化焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • 2026最新教育垂直领域学科大模型与教学智能体建设方案排行 - 起跑123
  • 如何3分钟完成Adobe软件快速激活:Adobe-GenP完整使用指南
  • JEEWMS issue3: `updateDataRule` 可改写角色数据规则
  • OneNote转Markdown终极指南:如何用onenote-md-exporter实现无损格式转换
  • 2026石家庄焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • 2026锡林郭勒盟焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • 东北景区文旅对讲运维科普 淡旺季对讲机通讯设备适配与故障标准化解决方案----黑龙江单工科技有限公司 - 无线电评测大师
  • 2026石嘴山焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • SSRF 302跳转
  • 2026新乡焊缝探伤检测权威机构排行 TOP 本地高频选择,无损检测 + UT+RT+PT 检测 附电话地址 - 中安检测集团
  • LLM上下文压缩:在有限窗口中保留关键信息的工程策略
  • 计算机毕业设计之办公耗材管理系统
  • 5年,一个程序员是如何把私有化在线客服系统做到第一名的