CVE-2026-82755: ash_authentication_oauth2_server serves tenant-specific OAuth metadata as publicly cacheable without Vary, enabling cross-tenant confusion
Use of Cache Containing Sensitive Information vulnerability in ash-project ashauthenticationoauth2server allows a shared HTTP cache to serve one tenant's OAuth discovery metadata to another tenant's clients.
The RFC 8414 and RFC 9728 metadata endpoints in AshAuthentication.Phoenix.Oauth2Server.ProtocolRouter return tenant-specific values (issuer, authorizationendpoint, tokenendpoint, jwksuri) when a tenant is set, but sent them with Cache-Control: public, max-age=3600 and no Vary. When the tenant is derived from something other than the URL (a header or the Host) and a shared cache sits in front, the cache key is the URL alone, so a stored response for one tenant is served to another for up to an hour. Affected clients may then send authorization codes and secrets to the wrong tenant's token endpoint and validate tokens against the wrong keys.
This issue affects ashauthenticationoauth2server: from 0.1.3 before 0.3.1.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
ash-project/ash_authentication_oauth2_serverto a version that resolves this vulnerability.Fixed in 0.3.1 - Configuration
Update the ProtocolRouter responses for tenant-specific OAuth discovery metadata (issuer, authorization_endpoint, token_endpoint, jwks_uri) so they are not publicly cacheable with Cache-Control: public, max-age=3600; use a non-shared-cache directive (e.g., Cache-Control: private, max-age=3600) to prevent a shared HTTP cache from serving one tenant’s metadata to another.
AshAuthentication.Phoenix.Oauth2Server.ProtocolRouter (RFC 8414/RFC 9728 metadata endpoints) Cache-Control = private, max-age=3600 - Configuration
Ensure the metadata responses include a Vary header (instead of having no Vary) so the cache key varies by tenant context when tenant is derived from something other than the URL (e.g., header or Host), preventing cross-tenant cache confusion for up to an hour.
AshAuthentication.Phoenix.Oauth2Server.ProtocolRouter (RFC 8414/RFC 9728 metadata endpoints) Vary = Tenant - Compensating control
If you have a shared HTTP cache or CDN in front of the OAuth2Server ProtocolRouter endpoints, configure it to avoid serving cached responses across tenants (e.g., separate caches per tenant or ensure caching is disabled/public caching is prevented) to prevent one tenant’s discovery metadata being returned to another tenant’s clients for up to 3600 seconds.
Event History
Frequently Asked Questions
Which deployments are exposed to cross-tenant metadata confusion?
Deployments are exposed when they use ash_authentication_oauth2_server versions from 0.1.3 before 0.3.1, derive the tenant from something other than the URL such as a header or Host, and place a shared HTTP cache in front of the metadata endpoints. A URL-only cache key can then cause one tenant's metadata response to be served to another tenant.
What must occur for exploitation to affect OAuth clients?
A shared cache must first store tenant-specific RFC 8414 or RFC 9728 metadata for a URL, then serve that cached response to a client of another tenant. The affected metadata includes the issuer, authorization endpoint, token endpoint, and JWKS URI, which may cause clients to send authorization codes or secrets to the wrong token endpoint or validate tokens using the wrong keys.
How long can an incorrect metadata response remain cached?
The affected endpoints send Cache-Control: public, max-age=3600. A wrongly shared response may therefore be served for up to one hour.
What can be done if upgrading is not immediately possible?
Avoid placing a shared HTTP cache in front of the tenant-specific metadata endpoints when tenant selection is derived from a header or Host rather than the URL. This removes the described URL-only shared-cache condition.