Internet Bug Bounty · Report #2401359
CVE-2024-25128: Apache Airflow: Authentication Bypass when Legacy OpenID(2.0) is in use as AUTH_TYPE
Summary
CVE-2024-25128: Vulnerability in custom, long deprecated OpenID (NOT OIDC) authentication method in Flask AppBuilder
Severity: moderate
Affected versions:
- Apache Airflow before 2.8.2
Description:
When Flask-AppBuilder configuration is set to AUTH_TYPE set to
AUTH_OID, it allows an attacker to forge an HTTP request that
could deceive the backend into using any requested OpenID service.
This vulnerability could grant an attacker unauthorised privilege access if a custom OpenID service is deployed by the attacker and accessible by the backend.
For more details and remediation, see the blog post here: https://airflow.apache.org/blog/fab-oid-vulnerability/
Credit: Islam Rzayev (finder)
Full Security Advisory: https://lists.apache.org/thread/kf5kyfl6626kmp1wlxm6h0gk7vobny0y
How it was found
When OpenID(2.0) is in use as Authentication Type, it is possible for an attacker to forge authentication to any existing account in the Target Airflow installation. This was possible via deceiving the backend of app to trust arbitrary OpenID 2.0 Identity Provider(even if the provider is not in the trusted IDP list in config). In conclusion, an attacker could deploy their own IDP and could alter the target app's authentication fully and gain unauthorized access.
The Impact is Critical but as OpenID(2.0) is a legacy mechanism, the severity was lowered to Medium on the basis of low usage probability.
Details:
Airflow uses Flask-AppBuilder as basic authenication and authorization manager under the hood. It is possible to configure the service in the Airflow config file for desired Authentication option. The Options for using OpenID 2.0 as auth type is as following:
AUTH_TYPE = AUTH_OIDshould be defined- Uncommenting the following lines:
{F3097175} As it is seen from the attachment, there is a predefined list of allowed IDPs, normally the backend should have checked for provided values(idp urls) from client with the allowed idp list in backend, but didn't.
Attack flow
When OpenID(2.0) is enabled, the login page of Airflow looks like this:
{F3097214}
Selecting a provider from list and clicking Sign In button triggers a request like this:
{F3097199}
The one body parameter of this POST request to /login/ page, openid is used to define IDP provider Url. An attacker could change this url to their malicious IDP and can make a fake authentication and deceive the backend to trust it(as the allowed providers check wasn't properly done).
For a quick Proof of Concept demonstration, 'https://openstackid.org' idp can be used:
{F3097206}
After successful auth with provider, the attacker will be redirected to Airflow and logged in as target existing user account:
{F3097209}
Leading to Full Account Hijacking
Advisory and Acknowledgement Details
The Project Advisory: https://lists.apache.org/thread/kf5kyfl6626kmp1wlxm6h0gk7vobny0y
The Github Advisory: https://github.com/dpgaspar/Flask-AppBuilder/security/advisories/GHSA-j2pw-vp55-fqqj
Screenshot of email from the Team for Acknowledgement:
████
Extra screenshot, from a part of report email:
██████████
Impact
Full Authentication Bypass via deceiving the backend server to trust arbitrary OpenID(2.0) IDPs.