Summary
The GET /api/v2/workspaces/{id}/acl endpoint in Coder returns group membership details, including personally identifiable information (PII) of group members, to any user who has been granted at least a use role on the workspace via its access control list.
Vulnerability Details
The workspace ACL endpoint checks only policy.ActionRead on the workspace object, which is satisfied by any user with the workspace use ACL role. When constructing the response, the handler fetches group member data using an elevated system context (dbauthz.AsSystemRestricted), bypassing the caller's actual RBAC permissions. The response serializes group members as ReducedUser objects.
As a result, the endpoint returns the following fields for every member of every group on the workspace ACL:
email
last_seen_at
login_type
status
created_at
Under normal RBAC enforcement, a basic organization member without ResourceGroupMember:read permission would not be able to view this data through any other API endpoint (e.g., GET /api/v2/groups/{id} correctly filters members based on the caller's permissions).
Impact
A low-privilege user who has been shared a workspace (with use access) can enumerate the full membership roster and PII of every group referenced in that workspace's ACL. This information could be used for:
- Harvesting email addresses for phishing campaigns
- Account reconnaissance using
login_type, status, and last_seen_at fields
- Enumerating organizational structure and group membership
Affected Component
- Endpoint:
GET /api/v2/workspaces/{workspace}/acl
- Source:
coderd/workspaces.go, function workspaceACL
- Product:
github.com/coder/coder/v2
Remediation
Upgrade to a version of Coder that fetches group membership using the caller's RBAC context rather than an elevated system context. In fixed versions, callers without ResourceGroupMember:read permission receive group identifiers and metadata only, with member rosters omitted from the response.
Patched versions
This issue is fixed in the following releases:
Credits
We'd like to thank Anthropic's Security Team (ANT-2026-22459) for independently disclosing this issue!
Summary
The
GET /api/v2/workspaces/{id}/aclendpoint in Coder returns group membership details, including personally identifiable information (PII) of group members, to any user who has been granted at least auserole on the workspace via its access control list.Vulnerability Details
The workspace ACL endpoint checks only
policy.ActionReadon the workspace object, which is satisfied by any user with the workspaceuseACL role. When constructing the response, the handler fetches group member data using an elevated system context (dbauthz.AsSystemRestricted), bypassing the caller's actual RBAC permissions. The response serializes group members asReducedUserobjects.As a result, the endpoint returns the following fields for every member of every group on the workspace ACL:
emaillast_seen_atlogin_typestatuscreated_atUnder normal RBAC enforcement, a basic organization member without
ResourceGroupMember:readpermission would not be able to view this data through any other API endpoint (e.g.,GET /api/v2/groups/{id}correctly filters members based on the caller's permissions).Impact
A low-privilege user who has been shared a workspace (with
useaccess) can enumerate the full membership roster and PII of every group referenced in that workspace's ACL. This information could be used for:login_type,status, andlast_seen_atfieldsAffected Component
GET /api/v2/workspaces/{workspace}/aclcoderd/workspaces.go, functionworkspaceACLgithub.com/coder/coder/v2Remediation
Upgrade to a version of Coder that fetches group membership using the caller's RBAC context rather than an elevated system context. In fixed versions, callers without
ResourceGroupMember:readpermission receive group identifiers and metadata only, with member rosters omitted from the response.Patched versions
This issue is fixed in the following releases:
Credits
We'd like to thank Anthropic's Security Team (ANT-2026-22459) for independently disclosing this issue!