CVE-2026-92771 Overview
CVE-2026-92771 is a broken access control vulnerability in Twenty, an open-source customer relationship management (CRM) platform. Versions prior to 2.35.0 fail to validate field and row permissions inside the groupBy-with-records GraphQL resolver. Authenticated users with canReadObjectRecords permission but canReadFieldValue set to false can retrieve restricted field values that the normal query path would deny. The flaw maps to [CWE-863: Incorrect Authorization] and stems from missing permission enforcement on a secondary resolver path.
Critical Impact
Authenticated low-privilege users can bypass field-level and row-level permission checks to read restricted CRM data, including fields explicitly denied by administrator-configured role permissions.
Affected Products
- Twenty versions prior to 2.35.0
- Twenty server package twenty-server (GraphQL API layer)
- Twenty v2.14.0 confirmed vulnerable per referenced source
Discovery Timeline
- 2026-09-16 - CVE-2026-92771 published to NVD
- 2026-09-16 - Last updated in NVD database
Technical Details for CVE-2026-92771
Vulnerability Analysis
The vulnerability resides in the group-by-with-records.service.ts resolver within the Twenty GraphQL API. The groupBy-with-records query aggregates records and returns representative rows for each group. Standard record-fetching paths in Twenty invoke the permission utility that filters both rows and fields based on the caller's role. The groupBy-with-records resolver skips these checks and returns raw record data directly from the underlying repository.
An authenticated user granted read access to an object, but explicitly denied read access to specific fields, can issue a groupBy query and receive the restricted field values in the response. Row-level restrictions applied through record-level permissions are similarly ignored. The result is confidentiality loss for any field or row that relies on Twenty's permission model to remain hidden from lower-privilege roles.
Root Cause
The root cause is missing invocation of the shared permission enforcement logic defined in permissions.utils.ts (lines 47-53) from the groupBy-with-records code path. The general repository layer applies these checks, but the group-by resolver constructs its response through a bypass path that never calls the utility. This is a classic authorization gap where a secondary API surface fails to mirror the controls enforced on the primary surface.
Attack Vector
The attack requires network access to the Twenty GraphQL endpoint and any valid authenticated session with canReadObjectRecords permission on the target object. The attacker submits a crafted groupBy GraphQL query targeting the object and requests fields marked canReadFieldValue: false in their role. The server returns the restricted values in the grouped result set. No user interaction, elevated privileges, or malware execution is required.
Refer to the VulnCheck advisory and the upstream issue tracker for the annotated query pattern.
Detection Methods for CVE-2026-92771
Indicators of Compromise
- GraphQL requests to the Twenty API containing groupByWithRecords or groupBy operations from user sessions with restricted field permissions.
- API responses returning field values that a user's role marks with canReadFieldValue: false.
- Repeated groupBy queries against sensitive objects such as Person, Company, or custom PII-bearing objects from a single low-privilege account.
Detection Strategies
- Enable GraphQL operation logging on twenty-server and audit for groupBy operations correlated against the caller's role definition.
- Compare returned field sets against the requesting user's canReadFieldValue matrix; flag any mismatch as a bypass event.
- Alert on anomalous volumes of aggregation queries from accounts that historically issue only standard findMany requests.
Monitoring Recommendations
- Forward Twenty server logs and reverse-proxy access logs to a centralized log platform for retention and query.
- Baseline normal GraphQL query patterns per role and alert on deviation, particularly on objects containing regulated data.
- Monitor the Twenty GitHub repository for follow-up advisories or additional resolver-level fixes.
How to Mitigate CVE-2026-92771
Immediate Actions Required
- Upgrade Twenty to version 2.35.0 or later, which enforces field and row permissions in the groupBy-with-records resolver.
- Inventory user accounts with canReadObjectRecords: true combined with restrictive canReadFieldValue settings and review recent GraphQL activity for those accounts.
- Temporarily restrict or disable non-essential low-privilege accounts on internet-exposed Twenty deployments until patching completes.
Patch Information
The fix is available in Twenty version 2.35.0. Review the Twenty GitHub repository release notes and the referenced source files group-by-with-records.service.ts and permissions.utils.ts to confirm the enforcement call is present in the deployed build.
Workarounds
- If patching cannot occur immediately, disable or firewall the groupByWithRecords GraphQL operation at an API gateway or reverse proxy layer.
- Elevate field-level restrictions to object-level restrictions by removing canReadObjectRecords from roles that must not access sensitive fields.
- Restrict Twenty GraphQL endpoint exposure to trusted networks or VPN-authenticated users until upgrade is complete.
# Example nginx rule to block groupByWithRecords operations pre-patch
location /graphql {
if ($request_body ~* "groupByWithRecords|groupBy\\(") {
return 403;
}
proxy_pass http://twenty-server:3000;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

