GHSA-49VV-25QX-MG44

Vulnerability from github – Published: 2026-04-22 14:38 – Updated: 2026-04-22 14:38
VLAI?
Summary
OpenRemote has Improper Access Control via updateUserRealmRoles function
Details

Summary

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.

Details

In 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.

```340:353:manager/src/main/java/org/openremote/manager/security/UserResourceImpl.java @Override public void updateUserRealmRoles(RequestParams requestParams, String realm, String userId, String[] roles) { try { identityService.getIdentityProvider().updateUserRealmRoles( realm, userId, roles); } catch (ClientErrorException ex) { ex.printStackTrace(System.out); throw new WebApplicationException(ex.getCause(), ex.getResponse().getStatus()); } catch (Exception ex) { throw new WebApplicationException(ex); } }


### PoC
1. 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`).
2. In Keycloak realm `master`, pick a **low-privilege** user (no `admin` realm role). Copy that user’s UUID (`<master-user-uuid>`).
3. Authenticate as the user from step 1 and obtain a Bearer access token (`<token>`) for `NEW_REALM`.
4. Replace placeholders and run:
```bash
curl -k -X PUT "https://<host>/api/<NEW_REALM>/user/master/userRealmRoles/<master-user-uuid>" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '["admin"]'
  1. In the Keycloak Admin Console, realm master, that user, Role mapping. Confirm the admin realm role is assigned.

Impact

An 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.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Maven",
        "name": "io.openremote:openremote-manager"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.22.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-41166"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-284"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-04-22T14:38:23Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "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\u0027re 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\u2019s 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 \u0027[\"admin\"]\u0027\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.",
  "id": "GHSA-49vv-25qx-mg44",
  "modified": "2026-04-22T14:38:23Z",
  "published": "2026-04-22T14:38:23Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/openremote/openremote/security/advisories/GHSA-49vv-25qx-mg44"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/openremote/openremote"
    },
    {
      "type": "WEB",
      "url": "https://github.com/openremote/openremote/releases/tag/1.22.1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:L",
      "type": "CVSS_V3"
    }
  ],
  "summary": "OpenRemote has Improper Access Control via updateUserRealmRoles function"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.


Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…