CVE-2025-25196 Overview
CVE-2025-25196 is an authorization bypass vulnerability affecting OpenFGA, a high-performance and flexible authorization/permission engine built for developers and inspired by Google Zanzibar. The vulnerability exists in OpenFGA versions prior to v1.8.4 (Helm chart < openfga-0.2.22, Docker < v1.8.4) and allows attackers to bypass authorization controls when certain Check and ListObject API calls are executed under specific conditions.
Critical Impact
This authorization bypass vulnerability can allow unauthorized access to protected resources when specific tuple configurations exist, potentially compromising the integrity of the entire authorization system.
Affected Products
- OpenFGA versions prior to v1.8.5
- OpenFGA Helm Charts prior to openfga-0.2.22
- OpenFGA Docker images prior to v1.8.4
Discovery Timeline
- 2025-02-19 - CVE-2025-25196 published to NVD
- 2025-12-31 - Last updated in NVD database
Technical Details for CVE-2025-25196
Vulnerability Analysis
The authorization bypass vulnerability in OpenFGA occurs due to improper handling of userset tuples when evaluating public access permissions. The flaw manifests when the authorization engine fails to properly distinguish between public access tuples and userset tuples of the same type during Check API or ListObjects API calls.
The vulnerability is triggered under a specific set of conditions:
- The Check API or ListObjects is called with a model that has a relation directly assignable to both public access AND userset with the same type
- A type-bound public access tuple is assigned to an object
- A userset tuple is NOT assigned to the same object
- The Check request's user field is a userset that has the same type as the type-bound public access tuple's user type
Under these conditions, the authorization engine incorrectly grants access based on the public access tuple when it should deny access because the specific userset relationship doesn't exist.
Root Cause
The root cause lies in the Check and ReverseExpand logic within OpenFGA's authorization evaluation. The vulnerability stems from CWE-285 (Improper Authorization), where the system fails to properly validate that a userset cannot be treated as a wildcard/public access tuple. When a user tuple is a userset (object relation), the code path incorrectly evaluated it against public assignability checks without first verifying that usersets, by definition, cannot match wildcard patterns.
Attack Vector
This vulnerability is exploitable over the network with low attack complexity, requiring low privileges and no user interaction. An authenticated attacker can craft malicious Check API or ListObjects API requests that exploit the improper authorization logic. By leveraging the type confusion between public access tuples and userset tuples, an attacker can gain unauthorized access to resources they should not be able to access.
The attack exploits the authorization model configuration where:
- A relation allows both public (type:*) and userset (type#relation) assignments
- An object has a public access tuple but lacks the specific userset tuple
- The attacker queries using a userset that matches the public tuple's type
// Security patch in internal/graph/check.go
// Source: https://github.com/openfga/openfga/commit/0aee4f47e0c642de78831ceb27bb62b116f49588
objectType := tuple.GetType(reqTupleKey.GetObject())
relation := reqTupleKey.GetRelation()
+ // if the user tuple is userset, by definition it cannot be a wildcard
+ if tuple.IsObjectRelation(reqTupleKey.GetUser()) {
+ return false
+ }
+
isPubliclyAssignable, _ := typesys.IsPubliclyAssignable(
typesystem.DirectRelationReference(objectType, relation), // target
tuple.GetType(reqTupleKey.GetUser()),
The patch adds an explicit check to return false if the user tuple is a userset (object relation), preventing it from being evaluated against public assignability logic.
// Security patch in pkg/server/commands/reverseexpand/reverse_expand.go
// Source: https://github.com/openfga/openfga/commit/0aee4f47e0c642de78831ceb27bb62b116f49588
return err
}
+func (c *ReverseExpandQuery) shouldCheckPublicAssignable(targetReference *openfgav1.RelationReference, userRef IsUserRef) (bool, error) {
+ _, userIsUserset := userRef.(*UserRefObjectRelation)
+ if userIsUserset {
+ // if the user is an userset, by definition it is not public assignable
+ return false, nil
+ }
+ publiclyAssignable, err := c.typesystem.IsPubliclyAssignable(targetReference, userRef.GetObjectType())
+ if err != nil {
+ return false, err
+ }
+ return publiclyAssignable, nil
+}
+
func (c *ReverseExpandQuery) readTuplesAndExecute(
ctx context.Context,
req *ReverseExpandRequest,
This additional patch introduces a helper function that explicitly checks if the user reference is a userset before evaluating public assignability, ensuring proper separation of authorization logic.
Detection Methods for CVE-2025-25196
Indicators of Compromise
- Unexpected successful authorization responses for userset-based Check API calls
- Anomalous access patterns to resources that should be restricted to specific usersets
- Authorization logs showing access grants for userset queries against objects with only public access tuples
- Discrepancies between expected and actual ListObjects API results
Detection Strategies
- Monitor OpenFGA Check API and ListObjects API responses for authorization decisions involving userset queries
- Implement logging to capture all authorization decisions with details about tuple types and user references
- Review authorization model configurations for relations that allow both public access and userset assignments with the same type
- Audit access logs for patterns where userset-based queries succeed against objects without corresponding userset tuples
Monitoring Recommendations
- Enable verbose logging on OpenFGA authorization endpoints to capture request details
- Implement alerting for unusual spikes in successful authorization checks
- Deploy network monitoring to track API call patterns to OpenFGA services
- Regularly audit authorization models for potentially vulnerable relation configurations
How to Mitigate CVE-2025-25196
Immediate Actions Required
- Upgrade OpenFGA to version v1.8.5 or later immediately
- Review authorization models for relations with both public access and userset assignments of the same type
- Audit recent authorization decisions for potential unauthorized access
- Implement additional access controls at the application layer as a defense-in-depth measure
Patch Information
OpenFGA has released version v1.8.5 which addresses this vulnerability and is backwards compatible. The fix is available through:
- OpenFGA: Upgrade to v1.8.5 or later
- Helm Charts: Upgrade to openfga-0.2.22 or later
- Docker: Pull image version v1.8.5 or later
The security patch is available in commit 0aee4f47e0c642de78831ceb27bb62b116f49588. For detailed information, see the GitHub Security Advisory.
Workarounds
- No known workarounds exist for this vulnerability
- Upgrading to v1.8.5 is the only recommended remediation
- Consider temporarily restricting access to OpenFGA APIs until the upgrade is complete
- Review and restrict network access to OpenFGA services to trusted sources only
# Upgrade OpenFGA using Helm
helm repo update
helm upgrade openfga openfga/openfga --version 0.2.22
# Or upgrade using Docker
docker pull openfga/openfga:v1.8.5
docker stop openfga-container
docker run -d --name openfga-container openfga/openfga:v1.8.5
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

