POSTS
Real-life OIDC Security (VI): Reusable state leads to DoS Amplification
This is the sixth post of a series on Single Sign-On and OpenID Connect 1.0 security. This post outlines how the missing requirement of the state
value within the OpenID Connect Core specification leads to real-life security issues. Namely, the Denial-of-Service Amplification attack is introduced with CVE-2020-14302 (Keycloak) as an example.
The series consists of following posts:
- [Overview] Common Issue Patterns and Derived Security Considerations
- [Implementation] Login Confusion
- [Implementation] Injection of CRLF sequences
- [Implementation] SSRF issues in real-life OIDC implementations
- [Specification] Redirect URI Schemes
- [Specification] Reusable State parameter
- [Responsible Disclosure] Lessons learned during Responsible Disclosure of OIDC/OAuth related issues
As you can see, we structure the series in an [Overview], attacks with concrete examples categorized in [Implementation] and [Specification], and finally lessons learned during the [Responsible Disclosure].
Note that in this post the state
value specification is analyzed and resulting DoS Amplification issues within implementations that follow this specification (i.e., Keycloak) are outlined.
Acknowledgment
We made the observations within this advisory during the execution of my master’s thesis on “Single Sign-On Security: Security Analysis of real-life OpenID Connect Implementations”. The thesis was written at the chair for network and data security of Ruhr University Bochum.
The advisors of my thesis are Dr.-Ing. Christian Mainka (@CheariX), Dr.-Ing. Vladislav Mladenov (@v_mladenov) and Prof. Dr. Jörg Schwenk (@JoergSchwenk). Huge “Thank you” for your continuous support! 🙂
Introduction
According to the OpenID Connect Core specification, the state
value is a recommended value to associate the Authentication Request with the Authentication Response [1, Section 3.1.2.1.]:
RECOMMENDED. Opaque value used to maintain state between the request and the callback. Typically, Cross-Site Request Forgery (CSRF, XSRF) mitigation is done by cryptographically binding the value of this parameter with a browser cookie.
The OIDC Core specification additionally discusses that invalidating state
values may prevent token reuse [1, Section 16.9.]:
Alternatively, the server MAY record the state of the use of the token and check the status for each request.
Finally, the OAuth 2.0 Security Best Current Practice draft advises to invalidate state
values to prevent leaked state
values from being reused [2, Section 4.2.]:
The “state” value SHOULD be invalidated by the client after its first use at the redirection endpoint. If this is implemented, and an attacker receives a token through the Referer header from the client’s web site, the “state” was already used, invalidated by the client and cannot be used again by the attacker.
To sum up: According to the OIDC Core specification, the state
value is RECOMMENDED and MAY be a single-usable-value. The OAuth 2.0 Security Best Current Practice draft claims that the state
SHOULD be invalidated after it was used once.
Denial-of-Service Amplification
A novel real-life attack scenario if the state
is not invalidated is the DoS Amplification attack. Note that this attack’s impact is conditional. For example, this vulnerability has a potentially higher impact in a hosted service than in a self-hosted environment.
Suppose the Service Provider allows reusing the state
parameter and does not implement an additional rate-limiting at the redirect_uri
endpoint. In that case, it can be exploited as an “amplifying proxy” for Denial-of-Service attacks. This is in some-regards comparable to previously known DNS Amplification Attacks.
It has been observed that the outgoing Token Request (back-channel) to the configured Token Endpoint can be multiple times larger than the Authentication Request (front-channel). A malicious actor could utilize this to launch a Denial-of-Service attack and spending limited bandwidth using the Service Provider as an amplifying proxy, as presented in the following:
An unauthenticated web attacker could only target the configured Identity Provider. A malicious Identity Provider can additionally specify an arbitrary web server as Token Endpoint with a long URL path and issue long Client Credentials on registration (either manual or using OpenID Connect Dynamic Client Registration), resulting in an even larger outgoing request.
If there is no rate limiting at the redirect_uri
endpoint, the attacker could continuously replay the Authentication Response including the valid state
, resulting in large outgoing Token Requests on each try.
Example: Keycloak (CVE-2020-14302)
Keycloak is an open-source Identity and Access Management Software (IAM) maintained by Red Hat. In addition, Keycloak is used as the base for Red Hat’s Red Hat Single Sign-On.
Attacker Model
Two attacker models could be considered (three if you also consider the high privileged malicious administrative user). A web attacker having no influence on the target of the Token Request could only target the already configured Identity Provider. A malicious Identity Provider using the OpenID Connect Discovery could additionally target arbitrary web servers accessible for the Service Provider.
Description
Keycloak as Service Provider provides dedicated redirect_uri
s for each Identity Provider: https://keycloak.local/auth/realms/{realm}/broker/{alias}/endpoint.
The redirect_uri
endpoint does not invalidate state
values if they are redeemed once. As a result, multiple requests to this endpoint including a valid state
value result in requests to the configured Token Endpoint being initiated by Keycloak.
A malicious administrative user or malicious Identity Provider could additionally increase the outgoing Token Request by choosing a looong path for the Token Endpoint URL and setting imaginary looong Client Credentials. As a result, one request to the Keycloak instance could be amplified multiple times compared to the request that is received at the victim server’s end.
Steps to reproduce
The steps to launching a Denial-of-Service attack using many large requests through Keycloak as amplifying proxy are the following:
- Configure the victim server as Token Endpoint with a long path and long Client Credentials (if the attacker model is a regular web attacker, this step is skipped).
- Start an OpenID Connect flow and obtain a valid
state
value (i.e., save a valid Authentication Response including thestate
). - After the Authentication Response is received, Keycloak tries to redeem the received
code
value at the victim web server. This request can be multiple times larger than the attacker’s request (Authentication Response). - Replay the obtained Authentication Response, on each try Keycloak sends a new HTTP request to the victim server.
Recommendation
For mitigating this issue, the state
should not only be bound to the End-User’s session but, additionally, be a one-time-usable value.
Responsible Disclosure
- 2020-06-16: Initial report to Red Hat via https://issues.redhat.com/projects/KEYCLOAK/.
- 2020-06-22: CVE-2020-14302 is assigned.
- 2020-10-20: Red Hat is informed that the publication of this post is scheduled for 2020-11-17.
References
[1] https://openid.net/specs/openid-connect-core-1_0.html
[2] https://tools.ietf.org/html/draft-ietf-oauth-security-topics-16
Thank you for reading this post! If you have any feedback, feel free to reach out via Mastodon, Twitter or LinkedIn. 👨💻
You can directly tweet about this post using this link. 🤓
Special thanks to Dr.-Ing. Christian Mainka (@CheariX), Dr.-Ing. Vladislav Mladenov (@v_mladenov) and Louis Jannett (@iphoneintosh) for your feedback on this post prior to publication! 🙂