{"id":"CVE-2026-41166","aliases":["EUVD-2026-25096","GHSA-49vv-25qx-mg44"],"status":"published","title":"OpenRemote has Improper Access Control via updateUserRealmRoles function","description":"OpenRemote is an open-source internet-of-things platform. Prior to version 1.22.1, a 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. Version 1.22.1 fixes the issue.","severity":{"version":"3.1","score":7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:L","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-12","score":0.00285,"percentile":0.21301,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-284"],"published":"2026-04-22T14:38:23Z","modified":"2026-11-11T23:10:00Z","fixes":[{"ecosystem":"Maven","package":"io.openremote:openremote-manager","fixed_in":["1.22.1"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"Maven","package":"io.openremote:openremote-manager","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.22.1"}]}]},{"source":"osv","ecosystem":"Maven","package":"io.openremote:openremote-manager","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.22.1"}]}],"versions":["1.10.0","1.11.0","1.11.1","1.11.2","1.11.3","1.12.0","1.12.1","1.12.3","1.13.0","1.13.1","1.14.0","1.15.0","1.15.1","1.15.2","1.16.1","1.17.0","1.17.1","1.17.2","1.17.3","1.18.0","1.19.0","1.2.0","1.2.1","1.2.2","1.2.3","1.2.4","1.20.0","1.20.1","1.20.2","1.21.0","1.22.0","1.3.0","1.3.1","1.3.2","1.3.3","1.3.4","1.3.5","1.4.0","1.5.0","1.6.0","1.6.2","1.6.3","1.6.4","1.6.5","1.7.0","1.8.0","1.8.1","1.9.0"]}],"products":[{"vendor":"openremote","product":"openremote"}],"references":[{"url":"https://github.com/openremote/openremote/security/advisories/GHSA-49vv-25qx-mg44","tags":["x_refsource_CONFIRM","exploit","Exploit","Vendor Advisory","advisory","web"]},{"url":"https://github.com/openremote/openremote/releases/tag/1.22.1","tags":["x_refsource_MISC","Product","Release Notes","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-41166","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-49vv-25qx-mg44"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/41xxx/CVE-2026-41166.json","tags":["advisory"]},{"url":"https://github.com/openremote/openremote","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-41166","title":"OpenRemote has Improper Access Control via updateUserRealmRoles function","description":"OpenRemote is an open-source internet-of-things platform. Prior to version 1.22.1, a 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. Version 1.22.1 fixes the issue.","status":"published","published":"2026-04-22T20:31:29.234Z","modified":"2026-04-28T03:55:21.242Z","cvss":[{"version":"3.1","score":7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:L","level":"high","assessor":"cna"}],"cwes":["CWE-284"],"updated_at":"2026-11-02T13:41:08.498858Z"}],"euvd":[{"id":"EUVD-2026-25096","description":"OpenRemote is an open-source internet-of-things platform. Prior to version 1.22.1, a 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. Version 1.22.1 fixes the issue.","status":"published","published":"2026-04-22T20:31:29Z","modified":"2026-04-28T03:55:21Z","cvss":[{"version":"3.1","score":7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:L","level":"high"}],"updated_at":"2026-11-02T19:24:16.972131Z"}],"ghsa":[{"id":"GHSA-49vv-25qx-mg44","title":"OpenRemote has Improper Access Control via updateUserRealmRoles function","description":"### 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 (`\u003cmaster-user-uuid\u003e`).\n3. Authenticate as the user from step 1 and obtain a Bearer access token (`\u003ctoken\u003e`) for `NEW_REALM`.\n4. Replace placeholders and run:\n```bash\ncurl -k -X PUT \"https://\u003chost\u003e/api/\u003cNEW_REALM\u003e/user/master/userRealmRoles/\u003cmaster-user-uuid\u003e\" \\\n  -H \"Authorization: Bearer \u003ctoken\u003e\" \\\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.","status":"published","published":"2026-04-22T14:38:23Z","modified":"2026-04-27T16:23:03Z","cvss":[{"version":"3.1","score":7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:L","level":"high"}],"cwes":["CWE-284"],"updated_at":"2026-11-02T14:39:58.897998Z"}],"nvd":[{"id":"CVE-2026-41166","description":"OpenRemote is an open-source internet-of-things platform. Prior to version 1.22.1, a 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. Version 1.22.1 fixes the issue.","status":"published","published":"2026-04-22T21:17:09.167Z","modified":"2026-11-11T23:10:00.263Z","cvss":[{"version":"3.1","score":7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:L","level":"high","assessor":"secondary"}],"cwes":["CWE-284"],"updated_at":"2026-11-12T01:26:58.520432Z"}],"osv":[{"id":"CVE-2026-41166","title":"OpenRemote has Improper Access Control via updateUserRealmRoles function","description":"OpenRemote is an open-source internet-of-things platform. Prior to version 1.22.1, a 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. Version 1.22.1 fixes the issue.","status":"published","published":"2026-04-22T20:31:29.234Z","modified":"2026-10-28T11:13:17.358187147Z","cvss":[{"version":"3.1","score":7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:L","level":"high"}],"cwes":["CWE-284"],"updated_at":"2026-11-02T15:45:03.424067Z"},{"id":"GHSA-49vv-25qx-mg44","title":"OpenRemote has Improper Access Control via updateUserRealmRoles function","description":"### 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 (`\u003cmaster-user-uuid\u003e`).\n3. Authenticate as the user from step 1 and obtain a Bearer access token (`\u003ctoken\u003e`) for `NEW_REALM`.\n4. Replace placeholders and run:\n```bash\ncurl -k -X PUT \"https://\u003chost\u003e/api/\u003cNEW_REALM\u003e/user/master/userRealmRoles/\u003cmaster-user-uuid\u003e\" \\\n  -H \"Authorization: Bearer \u003ctoken\u003e\" \\\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.","status":"published","published":"2026-04-22T14:38:23Z","modified":"2026-05-05T16:00:53.382967Z","cvss":[{"version":"3.1","score":7,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:L","level":"high"}],"cwes":["CWE-284"],"updated_at":"2026-11-02T15:46:36.782754Z"}]}}
