CVE-2026-61709 Overview
OpenFGA contains an authorization bypass in the ListUsers API that can return users who should be excluded from a relation. The flaw affects intersection expressions that combine a base operand with a but not excluded operand. When the base grant comes through a type-bound public wildcard and the excluded user also has a concrete tuple through another intersection operand, expandIntersection incorrectly counts the user as authorized. Applications that rely on ListUsers for enumeration or access enforcement may therefore treat explicitly excluded principals as authorized. OpenFGA fixed the defect in version 1.18.1.
Critical Impact
Excluded users can be enumerated as authorized through the ListUsers API, weakening but not deny semantics in intersection-based authorization models [CWE-281].
Affected Products
- OpenFGA authorization and permission engine
- All OpenFGA releases prior to v1.18.1
- Applications consuming the ListUsers gRPC/HTTP API for access decisions
Discovery Timeline
- 2026-09-16 - CVE-2026-61709 published to NVD
- 2026-09-16 - Last updated in NVD database
Technical Details for CVE-2026-61709
Vulnerability Analysis
OpenFGA evaluates intersection relations by counting how many operands return a candidate user, including matches through type-bound public wildcards. The ListUsers command implements this logic in pkg/server/commands/listusers/list_users_rpc.go inside the expandIntersection function. The function aggregates counts from foundUsersCountMap and considers the user authorized once the count equals the number of intersection operands.
The bug arises when a relation combines a base operand with a but not excluded operand, such as (member but not banned) and active. If the base grant comes from a public wildcard like user:* and the excluded user also holds a concrete tuple through another intersection operand, the wildcard and concrete tuple contributions sum to the operand count. expandIntersection returns the user before checking excludedUsersMap, so the exclusion is silently discarded.
Downstream consumers that call ListUsers to enumerate members or make allow/deny decisions receive results that contradict the model's but not semantics. This is an authorization bypass classified under Improper Preservation of Permissions [CWE-281].
Root Cause
The root cause is a missing precedence check between exclusion and intersection accounting. foundUsersCountMap is evaluated before entries in excludedUsersMap are removed, so an explicitly excluded principal can satisfy the intersection when wildcard expansion and concrete tuples align.
Attack Vector
An authenticated caller with low privileges can query the ListUsers API against a store whose authorization model uses the vulnerable intersection pattern. No user interaction is required. The attack complexity is high because it depends on a specific model shape combining wildcard grants, intersection operands, and exclusion tuples.
// Patch: pkg/server/commands/listusers/list_users_rpc.go
for key, count := range foundUsersCountMap {
// A user may have already been explicitly excluded by an operand, and cannot satisfy the intersection
// e.g. the banned relation here: `(member but not banned) and active`
if _, excluded := excludedUsersMap[key]; excluded {
continue
}
// Compare the number of times the specific user was returned for
// all intersection operands plus the number of wildcards.
// If this summed value equals the number of operands, the user satisfies
}
Source: GitHub Commit 171806c
Detection Methods for CVE-2026-61709
Indicators of Compromise
- ListUsers responses that include principals matching tuples written to an excluded relation in the same store
- Authorization models that combine intersection operators with but not exclusions and type-bound public wildcards such as user:*
- Application logs showing access granted to users who appear in a banned, revoked, or equivalent excluded relation
Detection Strategies
- Diff ListUsers output against Check results for the same object and relation; discrepancies indicate the bypass path is being triggered
- Inspect deployed authorization models for the pattern (A but not B) and C where A is granted via a wildcard and B has concrete tuples
- Enable OpenFGA server access logs and correlate ListUsers calls with subsequent privileged actions in downstream applications
Monitoring Recommendations
- Track the OpenFGA server version reported at startup and alert when instances remain below v1.18.1
- Monitor for unexpected growth in ListUsers result sets after tuple writes to exclusion relations
- Emit audit events from applications whenever an access decision is derived from ListUsers rather than Check, and review those events for excluded-principal patterns
How to Mitigate CVE-2026-61709
Immediate Actions Required
- Upgrade OpenFGA to v1.18.1 or later across all server replicas
- Audit authorization models for intersection relations that combine wildcards and but not clauses, and validate expected behavior with test tuples
- Where feasible, replace ListUsers-based enforcement with Check calls for individual principals until upgrade is complete
Patch Information
The fix is included in OpenFGA Release v1.18.1 and delivered by commit 171806c. The patch adds an early excludedUsersMap lookup in expandIntersection so that excluded users are skipped before intersection counts are compared. Full advisory details are in GHSA-g3pg-frfm-pr2m.
Workarounds
- Use Check instead of ListUsers for authorization decisions on principals sourced from other channels
- Refactor affected models to avoid granting the base intersection operand through a type-bound public wildcard when a but not exclusion is present
- Add application-layer deny lists that re-verify excluded principals after receiving ListUsers results
# Upgrade OpenFGA container deployments to the patched release
docker pull openfga/openfga:v1.18.1
docker stop openfga && docker rm openfga
docker run -d --name openfga -p 8080:8080 -p 8081:8081 -p 3000:3000 \
openfga/openfga:v1.18.1 run
# Verify running version
curl -s http://localhost:8080/healthz
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.
