Apr 9, 2026·6 min read·1 visit
OpenFGA leaks the preshared authentication key in the `/playground` HTML response. Unauthenticated attackers can extract this key to gain full API access. Administrators must upgrade to v1.14.0 or disable the playground.
OpenFGA versions 1.13.1 and prior are vulnerable to sensitive information disclosure when configured with preshared-key authentication and the built-in playground enabled. The server inadvertently embeds the preshared API key into the HTML response of the `/playground` endpoint, allowing unauthenticated attackers to extract the credential and gain administrative access to the OpenFGA API.
OpenFGA is an open-source, high-performance authorization and permission engine inspired by Google's Zanzibar paper. It allows developers to model fine-grained access control using relationship-based access control (ReBAC). To assist developers in building and testing these authorization models, OpenFGA includes a built-in web-based UI known as the playground, typically served at the /playground endpoint.
The engine supports multiple authentication methods to secure its API endpoints, including OIDC and preshared keys. When configured to use preshared-key authentication (authentication.method: preshared), clients must provide a static API key in the Authorization header to interact with the service. This key acts as the primary defense mechanism against unauthorized access to the authorization data.
The vulnerability, identified as GHSA-68M9-983M-F3V5, manifests when the server is run with both preshared-key authentication and the playground enabled. The server logic responsible for rendering the playground inadvertently leaks the preshared key directly into the client-facing HTML response. An unauthenticated attacker with network access to the playground can extract this credential, entirely bypassing the intended authentication boundary.
The root cause of this vulnerability lies in the server-side rendering pipeline used to serve the playground application. Modern web applications often require configuration data to be passed from the backend server to the frontend client during initial loading. This process, commonly known as state hydration or configuration injection, involves serializing server-side configuration objects into the initial HTML document.
In vulnerable versions of OpenFGA, the server-side logic constructs a configuration struct to pass to the playground's frontend template. This struct is designed to inform the client-side application about the server's environment, active endpoints, and authentication requirements. However, the logic fails to explicitly filter or sanitize the configuration object before serialization.
Consequently, the raw preshared API key (preshared-key), which is loaded into the server's global configuration state at startup, is included in the data structure passed to the templating engine. The templating engine subsequently writes this sensitive value into the HTML response, typically embedding it within a <script> tag or assigning it to a global JavaScript variable.
This behavior violates the principle of least privilege for data exposure, resulting in CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor). The application incorrectly assumes that the configuration object being serialized contains only public or client-safe metadata.
The vulnerability stems from passing unfiltered configuration data directly into Go's HTML template rendering function. When the /playground HTTP handler processes an incoming GET request, it gathers the necessary server settings to render the UI.
Prior to the patch, the HTTP handler simply passed a broader configuration object that retained the preshared-key field. Because Go's JSON marshaler processes all exported fields of a struct unless explicitly ignored via struct tags (json:"-"), the sensitive key was serialized into the payload destined for the client browser.
The remediation strategy implemented in version 1.14.0 involves strict filtering of the configuration object before it reaches the templating engine. The fix ensures that a dedicated, sanitized struct—containing only the specific fields required by the frontend—is constructed and passed to the template.
By decoupling the server's internal configuration state from the data transfer object (DTO) used for client rendering, the developers eliminate the risk of inadvertent credential leakage. This explicit field mapping ensures that even if new sensitive configuration options are added to the server in the future, they will not automatically propagate to the playground UI.
Exploiting this vulnerability requires zero authentication and only basic HTTP interaction capabilities. The attacker's primary requirement is network line-of-sight to the vulnerable OpenFGA server's /playground endpoint. The playground is often exposed on port 8080 by default, alongside the primary API endpoints.
The attack begins with a standard HTTP GET request to the /playground route. Because the playground is intended to be the entry point where developers input credentials or construct queries, the endpoint itself is inherently unauthenticated.
curl -s http://openfga.example.com:8080/playground | grep -i "preshared"Upon receiving the HTML response, the attacker inspects the page source. The embedded preshared key is typically located within a JSON configuration object nested inside a <script> block. The attacker extracts this cleartext string.
Once the key is acquired, the attacker possesses the necessary material to authenticate against the core OpenFGA API. They can format the extracted value into a standard HTTP Authorization header (Authorization: Bearer <extracted_key>). This token grants them the same privileges as the legitimate administrator or service account that was intended to use the preshared key.
The security impact of a compromised OpenFGA preshared key is highly severe. OpenFGA acts as the central source of truth for authorization decisions within an organization's architecture. Compromising the authentication layer of the OpenFGA API grants the attacker full administrative control over the authorization state.
With administrative access, an attacker can invoke the Write endpoint to arbitrarily manipulate relationship tuples. This allows them to grant themselves or other compromised accounts elevated permissions in downstream systems that rely on OpenFGA for access control. For example, the attacker could insert a tuple asserting that their user account is an owner of a sensitive target resource.
Furthermore, the attacker gains read access to all existing authorization models and tuple data. This exposes the entire permission graph of the dependent applications, potentially revealing sensitive organizational structures, resource identifiers, and user roles. The attacker can also modify or delete the authorization models entirely, leading to a severe denial-of-service condition for any application relying on the engine to enforce access policies.
The primary and most robust remediation for this vulnerability is to upgrade the OpenFGA server to version v1.14.0 or later. The patched version corrects the server-side rendering logic to ensure that sensitive configuration parameters, including the preshared key, are stripped before the playground HTML is generated.
If an immediate upgrade is not operationally feasible, administrators must disable the playground endpoint. This can be achieved by updating the OpenFGA configuration file to set playground.enabled: false. Alternatively, operators can pass the --playground-enabled=false command-line flag when starting the OpenFGA binary. Disabling the playground completely neutralizes the attack vector without impacting the core authorization API functionality.
As a critical post-incident mitigation step, any preshared keys used on vulnerable instances where the playground was accessible to untrusted networks must be considered compromised. Administrators must generate new cryptographic keys, update the OpenFGA configuration, and rotate the credentials in all dependent client applications. Finally, it is an architectural best practice to never expose the playground interface in production environments, regardless of the OpenFGA version or authentication method in use.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
OpenFGA OpenFGA | <= 1.13.1 | 1.14.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-200 |
| Attack Vector | Network |
| Authentication | None Required |
| CVSS Score | 7.5 |
| Impact | Credential Exposure / API Compromise |
| Exploit Status | Proof of Concept |
| KEV Status | Not Listed |
The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.