MicroCommunity issue1: Confirmed Vulnerability

Vulnerability call chain

1.1 Summary

MicroCommunity has a missing authorization vulnerability: Confirmed Vulnerability. A user with access to this action can bind a high-privilege role to themselves or another staff account, causing privilege escalation across the backend permission system

  • Security impact: A user with access to this action can bind a high-privilege role to themselves or another staff account, causing privilege escalation across the backend permission system

1.2 Exploit path

  1. Request reaches AppController.servicePost through /app/{service}. 2. AppController performs action-level hasPrivilege for /app/role.saveRoleStaff. 3. SaveRoleStaffCmd.validate only checks that roleId exists and staffs is non-empty. 4. SaveRoleStaffCmd.doCmd loops through staffs and writes: - staffs[].staffId -> p_privilege_user.user_id - roleId -> p_privilege_user.p_id - PrivilegeUserDto.PRIVILEGE_FLAG_GROUP -> p_privilege_user.privilege_flag 5. Downstream menu/resource authorization uses p_privilege_user and p_privilege_rel to determine granted permissions

1.3 Key code evidence

  1. app/role.saveRoleStaff

Evidence location: https://github.com/java110/MicroCommunity/blob/master/app/role.saveRoleStaff
2. app/add.privilege.PrivilegeGroup

Evidence location: https://github.com/java110/MicroCommunity/blob/master/app/add.privilege.PrivilegeGroup
3. app/role.saveStaffCommunity

Evidence location: https://github.com/java110/MicroCommunity/blob/master/app/role.saveStaffCommunity
4. app/owner.saveOwnerMember

Evidence location: https://github.com/java110/MicroCommunity/blob/master/app/owner.saveOwnerMember
5. app/owner.editOwnerMember

Evidence location: https://github.com/java110/MicroCommunity/blob/master/app/owner.editOwnerMember
6. app/ownerSettled.saveOwnerSettledApply

Evidence location: https://github.com/java110/MicroCommunity/blob/master/app/ownerSettled.saveOwnerSettledApply
7. service-api/src/main/java/com/java110/api/controller/app/AppController.java

Evidence location: https://github.com/java110/MicroCommunity/blob/master/service-api/src/main/java/com/java110/api/controller/app/AppController.java#L83

   80       */
   81  
   82      @RequestMapping(path = "/{service:.+}", method = RequestMethod.POST)
   83      @ApiOperation(value = "资源post请求", notes = "test: 返回 2XX 表示服务正常")
   84      @ApiImplicitParam(paramType = "query", name = "service", value = "用户编号", required = true, dataType = "String")
   85      @Java110Lang
   86      public ResponseEntity<String> servicePost(@PathVariable String service,
  1. service-api/src/main/java/com/java110/api/controller/app/AppController.java

Evidence location: https://github.com/java110/MicroCommunity/blob/master/service-api/src/main/java/com/java110/api/controller/app/AppController.java#L103

  100              IPageData pd = (IPageData) request.getAttribute(CommonConstant.CONTEXT_PAGE_DATA);
  101              //todo 根据登录用户 的权限 校验 用户是否有权限访问该接口,此时的"/app/" + service 为 开发这账户 菜单权限下的资源地址
  102              privilegeSMOImpl.hasPrivilege(restTemplate, pd, "/app/" + service);
  103              //todo 进入 接口相关 业务处理
  104              responseEntity = apiSMOImpl.doApi(postInfo, headers,request);
  105              //todo 写入 token
  106              wirteToken(request,pd,service,responseEntity);
  1. service-user/src/main/java/com/java110/user/cmd/role/SaveRoleStaffCmd.java

Evidence location: https://github.com/java110/MicroCommunity/blob/master/service-user/src/main/java/com/java110/user/cmd/role/SaveRoleStaffCmd.java#L84

   81                  throw new CmdException("保存数据失败");
   82              }
   83          }
   84  
   85          cmdDataFlowContext.setResponseEntity(ResultVo.success());
   86      }
   87  }
  1. service-user/src/main/java/com/java110/user/cmd/role/SaveRoleStaffCmd.java

Evidence location: https://github.com/java110/MicroCommunity/blob/master/service-user/src/main/java/com/java110/user/cmd/role/SaveRoleStaffCmd.java#L122
11. service-user/src/main/java/com/java110/user/cmd/role/SaveRoleStaffCmd.java

Evidence location: https://github.com/java110/MicroCommunity/blob/master/service-user/src/main/java/com/java110/user/cmd/role/SaveRoleStaffCmd.java#L124
12. service-user/src/main/java/com/java110/user/cmd/role/SaveRoleStaffCmd.java

Evidence location: https://github.com/java110/MicroCommunity/blob/master/service-user/src/main/java/com/java110/user/cmd/role/SaveRoleStaffCmd.java#L130

2. Existing checks and why they fail

hasPrivilege only proves the caller may invoke the route. It does not prove that the caller may grant the specific roleId to the specific staffId. The mapper insert has no database-level constraint enforcing grant hierarchy or management scope.

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.

Before saving the binding:

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.
posted @ 2026-06-18 12:40  Aibot  阅读(8)  评论(0)    收藏  举报