{"id":"CVE-2026-41166","aliases":["GHSA-49vv-25qx-mg44"],"url":"https://o3.security/vulnerability/CVE-2026-41166","summary":"OpenRemote has Improper Access Control via updateUserRealmRoles function","details":"### Summary\nA user who has `write:admin` in one Keycloak realm can call the Manager API to update **Keycloak realm roles** for users in **another** realm, including **`master`**. The handler uses the `{realm}` path segment when talking to the identity provider but does not check that the caller may administer that realm. This could result in a privilege escalation to `master` realm administrator if the attacker controls any user in `master` realm.\n\n### Details\nIn `manager/src/main/java/org/openremote/manager/security/UserResourceImpl.java`, there is no check to validate if the caller should be able to administer a realm they're trying to update.\n\n```340:353:manager/src/main/java/org/openremote/manager/security/UserResourceImpl.java\n    @Override\n    public void updateUserRealmRoles(RequestParams requestParams, String realm, String userId, String[] roles) {\n        try {\n            identityService.getIdentityProvider().updateUserRealmRoles(\n                realm,\n                userId,\n                roles);\n        } catch (ClientErrorException ex) {\n            ex.printStackTrace(System.out);\n            throw new WebApplicationException(ex.getCause(), ex.getResponse().getStatus());\n        } catch (Exception ex) {\n            throw new WebApplicationException(ex);\n        }\n    }\n```\n\n### PoC\n1. Create a **new** Keycloak realm other than `master`. Add a user and grant that user the OpenRemote client role `write:admin`. Remember the realm name (call it `NEW_REALM`).\n2. In Keycloak realm `master`, pick a **low-privilege** user (no `admin` realm role). Copy that user’s UUID (`<master-user-uuid>`).\n3. Authenticate as the user from step 1 and obtain a Bearer access token (`<token>`) for `NEW_REALM`.\n4. Replace placeholders and run:\n```bash\ncurl -k -X PUT \"https://<host>/api/<NEW_REALM>/user/master/userRealmRoles/<master-user-uuid>\" \\\n  -H \"Authorization: Bearer <token>\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '[\"admin\"]'\n```\n5. In the Keycloak Admin Console, realm master, that user, Role mapping. Confirm the admin realm role is assigned.\n### Impact\nAn attacker with the OpenRemote client role write:admin in any realm can call this API with {realm} set to another realm (for example master) and change Keycloak realm roles for users there. That can grant admin on master to a user UUID they target, which gives Keycloak administrator access for the master realm.","published":"2026-04-22T20:31:29.234Z","modified":"2026-08-12T16:24:11.020210Z","cvss":{"score":7,"severity":"HIGH","vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:L"},"epss":{"score":0.00285,"percentile":0.20842,"asOf":"2026-08-12"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"Maven","name":"io.openremote:openremote-manager","fixedVersion":"1.22.1"}],"fix":null,"references":[{"type":"WEB","url":"https://github.com/openremote/openremote/releases/tag/1.22.1"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/41xxx/CVE-2026-41166.json"},{"type":"ADVISORY","url":"https://github.com/openremote/openremote/security/advisories/GHSA-49vv-25qx-mg44"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-41166"},{"type":"PACKAGE","url":"https://github.com/openremote/openremote"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T16:24:11.020210Z"}}