62 lines
4.6 KiB
Markdown
62 lines
4.6 KiB
Markdown
|
# CVE-2023-48228
|
||
|
|
||
|
_Reported by [@Sapd](https://github.com/Sapd)_
|
||
|
|
||
|
## OAuth2: Insufficient PKCE check
|
||
|
|
||
|
### Summary
|
||
|
|
||
|
When initialising a OAuth2 flow with a `code_challenge` and `code_method` (thus requesting PKCE), the SSO provider (authentik) **must** check if there is a matching **and** existing `code_verifier` during the token step.
|
||
|
|
||
|
authentik checks if the contents of code*verifier is matching \*\*\_ONLY*\*\* when it is provided. When it is left out completely, authentik simply accepts the token request with out it; even when the flow was started with a `code_challenge`.
|
||
|
|
||
|
### Patches
|
||
|
|
||
|
authentik 2023.8.5 and 2023.10.4 fix this issue.
|
||
|
|
||
|
### Details
|
||
|
|
||
|
The `code_verifier` is only checked when the user provides it. Note that in line 209 there is a check if the code_parameter is left out. But there is no check if the PKCE parameter simply was omitted WHEN the request was started with a `code_challenge_method`.
|
||
|
|
||
|
This oversight likely did not stem from a coding error but from a misinterpretation of the RFC, where the backward compatibility section may be somewhat confusing.
|
||
|
https://datatracker.ietf.org/doc/html/rfc7636#section-4.5
|
||
|
RFC7636 explicitly says in Section 4.5:
|
||
|
|
||
|
> The "code_challenge_method" is bound to the Authorization Code when
|
||
|
> the Authorization Code is issued. That is the method that the token
|
||
|
> endpoint MUST use to verify the "code_verifier".
|
||
|
|
||
|
Section 5, Compatibility
|
||
|
|
||
|
> Server implementations of this specification MAY accept OAuth2.0
|
||
|
> clients that do not implement this extension. If the "code_verifier"
|
||
|
> is not received from the client in the Authorization Request, servers
|
||
|
> supporting backwards compatibility revert to the OAuth 2.0 [[RFC6749](https://datatracker.ietf.org/doc/html/rfc6749)]
|
||
|
> protocol without this extension.
|
||
|
|
||
|
Section 5, Compatibility, allows server implementations of this specification to accept OAuth 2.0 clients that do not implement this extension. However, if a `code_verifier` is not received from the client in the Authorization Request, servers that support backward compatibility should revert to the standard OAuth 2.0 protocol sans this extension (including all steps).
|
||
|
|
||
|
It should be noted that this does not mean that the `code_verifier` check can be disregarded at any point if the initial request included `code_challenge` or `code_challenge_method`. Since Authentik supports PKCE, it **MUST** verify the code_verifier as described in Section 4.5 **AND** fail if it was not provided.
|
||
|
|
||
|
Ofc verification can be skipped if the original authorization request did not invoke PKCE (no `code_challenge_method` and no `code_challenge`).
|
||
|
|
||
|
Failure to check the `code_verifier` renders the PKCE flow ineffective. This vulnerability particularly endangers public or hybrid clients, as their `code` is deemed non-confidential.
|
||
|
|
||
|
While not explicitly stated in the standard, it is generally recommended that OAuth2 flows accepting public clients should enforce PKCE - at least when redirecting to a non HTTPS URL (like http or an app link).
|
||
|
|
||
|
### Impact
|
||
|
|
||
|
The vulnerability poses a high risk to both public and hybrid clients.
|
||
|
When for example a mobile app implements oauth2, a malicious app can simply also register the same in-app-link (e.g. `mycoolapp://oauth2`) for the redirect callback URL, possibly receiving `code` during callback. With PKCE working, a malicious app would still receive a `code` but the `code` would not work without the correct unhashed code-challenge.
|
||
|
This is especially problematic, because authentik claims to support PKCE, and a developer can expect that the proper checks are in place. Note that app-links cannot be protected by HTTPS or similar mechanisms.
|
||
|
|
||
|
Note also that this vulnerability poses a threat to confidential clients. Many confidential clients act as a proxy for OAuth2 API requests, typically from mobile apps or single-page applications. These proxies relay `code_challenge`, `code_challenge_method` (in auth request, which most libraries force and provide on default settings) and `code_verifier` in the token request unchanged and supplement the CLIENT_SECRET which only the relay knows. The relay can but does not have to check for an existing `code_verifier` as the standard does not define that PKCE can be ignored on confidential clients during the token request when the client requested PKCE during the authorization request.
|
||
|
|
||
|
An attacker could potentially gain full access to the application. If the code grants access to an admin account, the confidentiality, integrity, and availability of that application are compromised.
|
||
|
|
||
|
### For more information
|
||
|
|
||
|
If you have any questions or comments about this advisory:
|
||
|
|
||
|
- Email us at [security@goauthentik.io](mailto:security@goauthentik.io)
|