HexBrain

Internet Bug Bounty · Report #2401359

CVE-2024-25128: Apache Airflow: Authentication Bypass when Legacy OpenID(2.0) is in use as AUTH_TYPE

Validstatus
mediumseverity
33upvotes
28 Apr 2024disclosed

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:

  1. AUTH_TYPE = AUTH_OID should be defined
  2. 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.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original