Description
Ory Oathkeeper is vulnerable to authentication bypass due to cache key confusion. The oauth2introspection authenticator cache does not distinguish tokens that were validated with different introspection URLs. An attacker can therefore legitimately use a token to prime the cache, and subsequently use the same token for rules that use a different introspection server.
Preconditions
Ory Oathkeeper has to be configured with multiple oauth2introspection authenticator servers, each accepting different tokens. The authenticators also must be configured to use caching. An attacker has to have a way to gain a valid token for one of the configured introspection servers.
Mitigation
Ory Oathkeeper now includes the introspection server URL in the cache key, preventing confusion of tokens.
Update to the patched version of Ory Oathkeeper. If that is not immediately possible, disable caching for oauth2introspection authenticators.
Description
Ory Oathkeeper is vulnerable to an authorization bypass via HTTP path traversal. An attacker can craft a URL containing path traversal sequences (e.g. /public/../admin/secrets) that resolves to a protected path after normalization, but is matched against a permissive rule because the raw, un-normalized path is used during rule evaluation.
Preconditions
Ory Oathkeeper rules are typically configured with patterns like:
/public/<.> → allow unauthenticated access /admin/<.> → require authentication
Without path normalization, a request to /public/../admin/secrets is matched against the raw path /public/../admin/secrets. This matches the /public/<.> rule, bypassing the authentication required for /admin/secrets. After Ory Oathkeeper permits the request, the upstream server normalizes the path and serves the protected /admin/secrets resource.
Mitigation
Going forward, Ory Oathkeeper normalizes the request path before performing rule matching and before forwarding. The path /public/../admin/secrets is normalized to /admin/secrets, which correctly matches the /admin/<.> rule and triggers authentication.
As an immediate mitigation, all requests reaching Oathkeeper should be normalized, as described in the section below. Oathkeeper should be upgraded to a fixed version as soon as possible.
Defense in depth: Cleaning paths before Oathkeeper
Even after this fix, it is good practice to normalize HTTP paths in the layers in front of Oathkeeper. This provides defense in depth and protects against similar bypasses in other components. The following examples show how to achieve this with common reverse proxies and CDNs.
Nginx
Nginx normalizes paths by default when using proxypass. Alternatively, use $uri (which Nginx normalizes) rather than $requesturi in your matching rules.
Envoy
Enable the normalizepath option (available since Envoy 1.14) to normalize the path components before matching and forwarding. See the <a href="https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/httpconnectionmanager/v3/httpconnectionmanager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-normalize-path" target="blank" rel="noopener noreferrer">Envoy docs on path normalization</a>.
Cloudflare
Cloudflare normalizes URLs by default. In the Cloudflare dashboard, ensure Normalize incoming URLs is enabled under Rules → Normalization. See the <a href="https://developers.cloudflare.com/rules/normalization/" target="blank" rel="noopener noreferrer">Cloudflare URL normalization docs</a>.
Description
Ory Oathkeeper is often deployed behind other components like CDNs, WAFs, or reverse proxies. Depending on the setup, another component might forward the request to the Oathkeeper proxy with a different protocol (http vs. https) than the original request. In order to properly match the request against the configured rules, Oathkeeper considers the X-Forwarded-Proto header when evaluating rules. The configuration option serve.proxy.trustforwardedheaders (defaults to false) governs whether this and other X-Forwarded- headers should be trusted. Oathkeeper did not properly respect this configuration, and would always consider the X-Forwarded-Proto header.
Preconditions
In order for an attacker to abuse this, an installation of Ory Oathkeeper needs to have distinct rules for HTTP and HTTPS requests. Also, the attacker needs to be able to trigger one but not the other rule. In this scenario, the attacker can send the same request but with the X-Forwarded-Proto header in order to trigger the other rule. We do not expect many configurations to meet these preconditions.
Mitigation
It is generally recommended to drop any unexpected headers as early as possible when a request is handled, e.g. in the WAF.
Ory Oathkeeper will correctly respect the serve.proxy.trustforwardedheaders configuration going forward, thereby eliminating the attack scenario. We recommend upgrading to a fixed version even if the preconditions are not met.
ORY Oathkeeper is an Identity & Access Proxy (IAP) and Access Control Decision API that authorizes HTTP requests based on sets of Access Rules. When you make a request to an endpoint that requires the scope foo using an access token granted with that foo scope, introspection will be valid and that token will be cached. The problem comes when a second requests to an endpoint that requires the scope bar is made before the cache has expired. Whether the token is granted or not to the bar scope, introspection will be valid. A patch will be released with v0.38.12-beta.1. Per default, caching is disabled for the oauth2introspection authenticator. When caching is disabled, this vulnerability does not exist. The cache is checked in func (a AuthenticatorOAuth2Introspection) Authenticate(...). From tokenFromCache() it seems that it only validates the token expiration date, but ignores whether the token has or not the proper scopes. The vulnerability was introduced in PR #424. During review, we failed to require appropriate test coverage by the submitter which is the primary reason that the vulnerability passed the review process.