Summary
A broken-access-control flaw in GET /api/v1/organizationuser allows any authenticated organization member including the lowest-privilege "member" role with empty permissions ([]) to retrieve the organization owner's full User entity including the owner's bcrypt password hash (credential) and tempToken/tokenExpiry. The route enforces no permission check (unlike the POST/PUT/DELETE verbs on the same router) and the backing service attaches the org owner's record without scrubbing secret fields that its sibling methods strip. A member can obtain the owner's password hash for offline cracking, leading to takeover of the highest-privileged account in the organization. This finding is related to CVE-2025-58434 but is a distinct, separately-exploitable vulnerability, a different endpoint (GET /api/v1/organizationuser), a different code path (readOrganizationUserByUserId) and an additional access-control defect (no permission check on the route, no requester-organization scoping) that CVE-2025-58434's fix did not address. Where CVE-2025-58434 exposed a reset tempToken, this path additionally exposes the owner's bcrypt credential hash to any authenticated member. The sanitizeUser scrub introduced by that advisory was not applied to this method.
Details
There are 2 issues:
-
No authorization on the read route. In packages/server/src/enterprise/routes/organization-user.route.ts, the GET handler (line 9) is registered with no checkPermission and no checkFeatureByPlan, while the POST/PUT/DELETE handlers on the same router (lines 11/13/15) all require checkPermission('users:manage'). Any authenticated session reaches the read.
-
Unscrubbed owner entity. The controller (organization-user.controller.ts:35, userId branch at ~68-69) passes the request's userId straight into readOrganizationUserByUserId with no scoping to the requester's own organization. That service method (organization-user.service.ts:158) re-fetches the organization owner's full User record via readUserById and assigns it raw to user.user (lines ~179-181). The sibling methods readOrganizationUserByOrganizationId (lines ~115-117) and readOrganizationUserByOrganizationIdRoleId (lines ~148-150) explicitly delete the credential, tempToken, and tokenExpiry fields before returning, this method does not. The owner-attach loop makes it worse than a self-read even when a member queries their own userId, the response contains the owner's secrets.
For contrast, GET /api/v1/workspaceuser (same query parameters) returns records with no user object and no credential confirming the leak is specific to the organization-user owner-attach path.
Confirmed present in flowiseai/flowise:3.1.2 and on current main.
PoC
Reproduced on a local self-hosted enterprise instance (multi-member orgs require an enterprise/cloud license; testing was confined to a locally licensed instance, as the policy does not authorize cloud testing). Requests carry the x-request-from: internal header that the UI sends on API calls.
- Owner A completes organization setup (
/organization-setup), creating org AcmeOrg and the owner account ownerA@example.com.
- As A, create an org role
ws-member with a single non-admin permission (e.g. chatflows:view) at /roles.

3. As A, invite `memberB@example.com` via User Management > Invite User, assigning workspace Default Workspace and role `ws-member`. B is created with organization role `member` (`org permissions []`).
- Member B completes onboarding through the real invite link
http://<host>/register?token=<inviteToken> (the token is normally delivered to the invitee by email, SMTP was unconfigured in the test instance, so it was read from the local DB as a stand-in, it is B's own onboarding token). B sets a password and logs in, B's session shows isOrganizationAdmin:false, org role member.
- As member B, send:
GET /api/v1/organizationuser?userId=<B's own userId> HTTP/1.1
Host: <host>
x-request-from: internal
Cookie: token=<B's session token>
The HTTP 200 response contains the owner's User object:
[{ "isOrgOwner": false, "userId": "<B's id>",
"user": { "email": "ownerA@example.com",
"credential": "$2a$10$bKrwB/b/XlvUzmTOSQZ80e7a4f4rI9CC/18c8KG5xtQLOtQzgZd/.",
"tempToken": null, "tokenExpiry": "..." } }]
Querying ?userId=<owner A's id> returns the same credential. Negative controls: the same GET with no session cookie > 401, B issuing POST /api/v1/organizationuser or POST /api/v1/role > 403 (B holds no management permission), confirming the read route is the only unguarded verb.
Impact
Broken access control leading to sensitive-data exposure (CWE-862, CWE-639, CWE-200) which in turn leads to privilege escalation. Any authenticated organization member with the lowest-privilege role obtains the organization owner's bcrypt password hash without victim interaction and without even needing the owner's user id (a self-id query returns the owner). The hash is crackable offline, weak or reused owner passwords yield full takeover of the highest-privileged account in the organization. The response also returns tempToken/tokenExpiry unscrubbed; for any target with a live tempToken (active password reset or pending invite) the same response discloses it, enabling tokenless account takeover via the password-reset flow not demonstrated here, as the test owner held no active token. Additionally, the route applies no requester-organization scoping so on multi-tenant deployments (Flowise Cloud/shared enterprise) a member of one organization could retrieve owners of other organizations by enumerating user ids a cross-tenant exposure inferred from the code path, not exercised in the single-org test.
Summary
A broken-access-control flaw in
GET /api/v1/organizationuserallows any authenticated organization member including the lowest-privilege "member" role with empty permissions ([]) to retrieve the organization owner's full User entity including the owner's bcrypt password hash (credential) andtempToken/tokenExpiry. The route enforces no permission check (unlike thePOST/PUT/DELETEverbs on the same router) and the backing service attaches the org owner's record without scrubbing secret fields that its sibling methods strip. A member can obtain the owner's password hash for offline cracking, leading to takeover of the highest-privileged account in the organization. This finding is related to CVE-2025-58434 but is a distinct, separately-exploitable vulnerability, a different endpoint (GET /api/v1/organizationuser), a different code path (readOrganizationUserByUserId) and an additional access-control defect (no permission check on the route, no requester-organization scoping) that CVE-2025-58434's fix did not address. Where CVE-2025-58434 exposed a reset tempToken, this path additionally exposes the owner's bcrypt credential hash to any authenticated member. The sanitizeUser scrub introduced by that advisory was not applied to this method.Details
There are 2 issues:
No authorization on the read route. In
packages/server/src/enterprise/routes/organization-user.route.ts, the GET handler (line 9) is registered with nocheckPermissionand no checkFeatureByPlan, while thePOST/PUT/DELETEhandlers on the same router (lines 11/13/15) all requirecheckPermission('users:manage'). Any authenticated session reaches the read.Unscrubbed owner entity. The controller (
organization-user.controller.ts:35, userId branch at ~68-69) passes the request's userId straight intoreadOrganizationUserByUserIdwith no scoping to the requester's own organization. That service method (organization-user.service.ts:158) re-fetches the organization owner's full User record viareadUserByIdand assigns it raw to user.user (lines ~179-181). The sibling methodsreadOrganizationUserByOrganizationId (lines ~115-117)andreadOrganizationUserByOrganizationIdRoleId (lines ~148-150)explicitly delete thecredential,tempToken, andtokenExpiryfields before returning, this method does not. The owner-attach loop makes it worse than a self-read even when a member queries their own userId, the response contains the owner's secrets.For contrast,
GET /api/v1/workspaceuser(same query parameters) returns records with no user object and no credential confirming the leak is specific to the organization-user owner-attach path.Confirmed present in flowiseai/flowise:3.1.2 and on current main.
PoC
Reproduced on a local self-hosted enterprise instance (multi-member orgs require an enterprise/cloud license; testing was confined to a locally licensed instance, as the policy does not authorize cloud testing). Requests carry the
x-request-from: internalheader that the UI sends on API calls./organization-setup), creating orgAcmeOrgand the owner accountownerA@example.com.ws-memberwith a single non-admin permission (e.g.chatflows:view) at/roles.http://<host>/register?token=<inviteToken>(the token is normally delivered to the invitee by email, SMTP was unconfigured in the test instance, so it was read from the local DB as a stand-in, it is B's own onboarding token). B sets a password and logs in, B's session showsisOrganizationAdmin:false, org rolemember.The HTTP 200 response contains the owner's User object:
Querying
?userId=<owner A's id>returns the same credential. Negative controls: the same GET with no session cookie > 401, B issuingPOST /api/v1/organizationuserorPOST /api/v1/role> 403 (B holds no management permission), confirming the read route is the only unguarded verb.Impact
Broken access control leading to sensitive-data exposure (CWE-862, CWE-639, CWE-200) which in turn leads to privilege escalation. Any authenticated organization member with the lowest-privilege role obtains the organization owner's bcrypt password hash without victim interaction and without even needing the owner's user id (a self-id query returns the owner). The hash is crackable offline, weak or reused owner passwords yield full takeover of the highest-privileged account in the organization. The response also returns
tempToken/tokenExpiryunscrubbed; for any target with a livetempToken(active password reset or pending invite) the same response discloses it, enabling tokenless account takeover via the password-reset flow not demonstrated here, as the test owner held no active token. Additionally, the route applies no requester-organization scoping so on multi-tenant deployments (Flowise Cloud/shared enterprise) a member of one organization could retrieve owners of other organizations by enumerating user ids a cross-tenant exposure inferred from the code path, not exercised in the single-org test.