JEEWMS BOPLA VULNs Report

 


JEEWMS 审计报告

说明

  • 项目: jeesite5 / JEEWMS

  • 方法: 仅基于当前仓库代码

  • 判定标准: 优先保留能闭合到“入口授权 → sink 写入 → 后续生效点”的接口

  • 结论性质: 本文为代码级初判,不等同最终裁决


漏洞接口一览

userController.do?saveUser
roleController.do?updateAuthority
roleController.do?updateOperation
roleController.do?updateDataRule
roleController.do?doAddUserToRole
/rest/user

Issue 1:userController.do?saveUser

对象: TSRoleUser / TSUserOrg
问题类型: assign(roleId), assign(orgId)

1. 风险分析

该接口在保存用户时,若缺少对 roleIdorgIds 的服务端上界校验,低权限后台用户就可能把任意目标用户绑定到更高权限角色或敏感组织下。
最严重时,会造成账户权限提升、跨组织数据访问,甚至间接获得系统管理能力。

2. 漏洞信息

  • 入口: UserController.java:581

  • 写入 sink:

    • UserController.java:643

    • UserController.java:664

  • 后续生效点:

    • LoginController.java:352

    • AuthInterceptor.java:241

  • 缺失检查:

    • 未校验操作者是否有权给目标用户分配该 roleId

    • 未校验操作者是否有权给目标用户分配该 orgId

3. 核验细节

入口仅做 URL 级鉴权,并读取 roleid / orgIds,随后直接重建:

  • t_s_user_org

  • t_s_role_user

说明当前写链把请求中的角色与组织关系当作可信输入,未做归属约束。

4. 安全建议

saveUser 落库前,对每个待写入的 roleIdorgId 做服务端白名单校验:

  • 只允许分配操作者实际可管理的角色和组织

  • 任一校验失败即拒绝整个更新请求

  • 不要只校验目标用户“是否可见”,还要校验“目标属性是否可分配”


Issue 2:roleController.do?updateAuthority

对象: TSRoleFunction
问题类型: assign(functionId)

1. 风险分析

若系统允许低权限后台用户调用该接口并更新角色权限,那么攻击者可把高危菜单或管理接口权限绑定给任意角色。
该角色下的所有用户在下次权限计算后都会获得越权访问能力,最终可扩大为批量权限提升系统管理权限接管

2. 漏洞信息

  • 入口: RoleController.java:580

  • 写入 sink:

    • RoleController.java:619

    • RoleController.java:640

  • 后续生效点:

    • LoginController.java:345

    • AuthInterceptor.java:233

  • 缺失检查:

    • 未校验目标 roleId 是否归当前操作者管理

    • 未校验 functionId 是否在可授予功能集内

3. 核验细节

入口只进入角色权限更新流程,但 sink 直接增删 TSRoleFunction,没有看到:

  • 角色管理范围校验

  • 功能授予白名单校验

因此“可更新角色”并不等于“可授予这些功能”。

4. 安全建议

在更新 TSRoleFunction 前同时校验:

  • 当前操作者对目标 roleId 的管理权限

  • 每个待授予 functionId 是否位于操作者可授予白名单内

任一校验失败即拒绝整个更新请求,并避免对原有权限做部分写入。


Issue 3:roleController.do?updateOperation

对象: TSRoleFunction
问题类型: assign(operation)

1. 风险分析

该链路更像 UI 控件隐藏/渲染链,而不是服务端放权链。
当前证据不足以证明它会把操作权限真正下发到服务端授权面。

2. 漏洞信息

  • 入口: RoleController.java:812

  • 写入 sink:

    • RoleController.java:834

    • RoleController.java:836

  • 后续读点:

    • SystemServiceImpl.java:214

    • AuthInterceptor.java:149

3. 核验细节

Reviewer 复核后认为,这条链闭合到的是:

  • 前端 UI 控件隐藏

  • 页面渲染逻辑

而不是服务端权限放权链,因此不构成漏洞成立条件。

4. 安全建议

当前可作为设计观察项保留,不纳入漏洞结论。


Issue 4:roleController.do?updateDataRule

对象: TSRoleFunction
问题类型: assign(dataRule)

1. 风险分析

如果 dataRule 可以被写入与 functionId 不匹配、或超出操作者授权范围的规则,那么后续查询链会把这些规则当成真实约束执行。
这会导致数据边界被错误放宽,最终引发跨部门、跨租户或敏感业务数据越权读取。

2. 漏洞信息

  • 入口: RoleController.java:875

  • 写入 sink:

    • RoleController.java:896

    • RoleController.java:899

  • 后续生效点:

    • SystemServiceImpl.java:358

    • AuthInterceptor.java:176

    • HqlGenerateUtil.java:331

  • 缺失检查:

    • dataRule 是否属于 functionId

    • dataRule 是否在当前操作者可授予范围内

3. 核验细节

这条链与 motivation case 最接近:

  • 入口只做粗粒度功能访问

  • sink 没有校验数据规则的归属关系

  • 后续服务端查询会直接信任写入结果

说明数据权限不是只在查询侧有效,写入侧也必须闭环。

4. 安全建议

在写入 TSRoleFunction.dataRule 前增加三类校验:

  • 当前操作者对目标 roleId 的管理权限

  • dataRulefunctionId 的合法归属关系

  • 每个数据规则是否位于操作者可授予白名单内

任一不满足即拒绝整个更新请求,并保持原有数据权限配置不变。


Issue 5:roleController.do?doAddUserToRole

对象: TSRoleUser
问题类型: assign(roleId), assign(userId)

1. 风险分析

若攻击者能够调用该接口并向任意角色添加用户,就可以把自己或其他目标用户加入高权限角色。
后续这些账户在登录或权限拦截时会获得对应菜单和接口权限,最终造成批量权限提升,甚至系统管理能力接管。

2. 漏洞信息

  • 入口: RoleController.java:947

  • 写入 sink:

    • RoleController.java:965

    • RoleController.java:981

  • 后续生效点:

    • LoginController.java:352

    • AuthInterceptor.java:241

  • 缺失检查:

    • 未校验目标 roleId 是否归当前操作者管理

    • 未校验这些 userId 是否允许被纳入该角色

3. 核验细节

入口进入角色加人流程后,sink 直接写 TSRoleUser,没有看到:

  • 角色管理边界控制

  • 用户纳入白名单控制

也就是说,只要接口可达,角色成员关系就可能被任意重组。

4. 安全建议

在写入 TSRoleUser 前同时校验:

  • 当前操作者对目标 roleId 的管理权限

  • 每个待加入 userId 是否位于操作者可管理且允许纳入该角色的白名单内

任一校验失败即拒绝整个请求,并避免产生部分绑定记录。


Issue 6:/rest/user

对象: TSUser
问题类型: read(TSUser.*), write(password|status|deleteFlag|userType|userName), delete(id)

1. 风险分析

/rest/* 被映射到 REST dispatcher,而 AuthInterceptor^rest/[a-zA-Z0-9_/]+$ 直接放行。
这意味着 UserRestController 暴露了未鉴权 CRUD 面,攻击者可直接读取、修改或删除用户记录,造成账号体系被接管,甚至引发业务不可用。

2. 漏洞信息

  • 接口: /rest/user

  • 问题类型:

    • 读:TSUser.*

    • 写:password / status / deleteFlag / userType / userName

    • 删:id

  • 关键代码:

    • web.xml:129

    • AuthInterceptor.java:95

    • UserRestController.java:47-108

    • TSBaseUser.java:27

    • CommonDao.java:138

3. 核验细节

当前链路表现为:

  • /rest/* 被统一放行

  • UserRestController 直接暴露 CRUD

  • 仅做 Bean Validation,不做登录态或角色校验

后续 TSUser 的敏感字段还会被登录/账户逻辑消费,因此一旦写入成功,影响不是局部的,而是会进入整套身份体系。

4. 安全建议

  • 取消 AuthInterceptor^rest/[a-zA-Z0-9_/]+$ 的无条件放行

  • /rest/user 分别增加:

    • 登录校验

    • 角色/权限校验

    • 字段级白名单绑定

    • 敏感字段输出过滤


总体结论

本次初筛的共性问题可以概括为:

入口有权限,但 sink 缺少对象级、属性级或授予上界的校验。

主要风险模式包括:

  1. 角色绑定越权

  2. 组织绑定越权

  3. 数据规则写入越权

  4. 未鉴权 REST 读写删

其中最值得优先修的是:

  • saveUser

  • updateAuthority

  • updateDataRule

  • /rest/user

posted @ 2026-05-06 14:22  Aibot  阅读(14)  评论(0)    收藏  举报