Vulnerability in long deprecated OpenID authentication method in Flask AppBuilder
Recently Islam Rzayev made us aware of a vulnerability in the long deprecated OpenID authentication method in Flask AppBuilder. This vulnerability allowed a malicious user to take over the identity of any Airflow UI user by forging a specially crafted request and implementing their own OpenID service. While this is an old, deprecated and almost not used authentication method, we still took the issue seriously.
This issue ONLY affects users who have AUTH_OID
set in their webserver_config.py
file as
AUTH_TYPE
. This is a very old and deprecated authentication method that is unlikely to be used by anyone.
We would like to advise even the small number of our users that still use this authentication method to take an immediate action and either upgrade to Apache Airflow 2.8.2 or switch to another authentication method (or apply a workaround we provide if they cannot do either of the above immediately).
Important to stress, because many of the users might get confused by the name, OpenID is NOT the same as OpenID Connect. Those are completely different protocols and while OpenID Connect (also known as OIDC) is a modern, widely used protocol, OpenID is a legacy protocol that has been deprecated more than 10 years ago and since then has been abandoned by almost everyone in the community, including all services in Flask AppBuilder example services that supported it, so it is highly unlikely someone is still using it.
Due to this highly unlikely configuration the Flask AppBuilder CVE is just “Moderate” not “Critical”. It affects a very small (if any) number of users and it’s not likely to be a target for an attack. However, we still advise our users who still use AUTH_OID to apply remediation.
This vulnerability is fixed in Flask Appbuilder 4.3.11 and Apache Airflow 2.8.2 uses that version of Flask Application Builder. We advise users who still use this authentication method to either switch to another authentication method or upgrade to Apache Airflow 2.8.2. If they cannot do either of these solutions quickly, they should apply the workaround provided below.
Impact
When Flask-AppBuilder 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.
This vulnerability is only exploitable when the application is using OpenID (not OpenID Connect also known as OIDC). Currently, this protocol is regarded as legacy, with significantly reduced usage.
Possible remediation
- Change your authentication method - if you are using
AUTH_OID
, there are almost no commercial services supporting it, it was deprecated 10 years ago and abandoned by nearly everyone in the community 4 years ago. Your best choice is to choose a different authentication method. - Upgrade to Apache Airflow 2.8.2 (which also upgrades to Flask-AppBuilder 4.3.11 that contains a fix)
- If upgrade is not possible, apply the workaround below
Workarounds
If upgrade or changing authentication method is not possible add the following to
your webserver_config.py
file to fix the issue:
import os
from flask import flash, redirect
from flask_appbuilder.security.forms import LoginForm_oid
from flask_appbuilder.security.views import AuthOIDView
from flask_appbuilder.views import expose
from airflow.www.security import AirflowSecurityManager
basedir = os.path.abspath(os.path.dirname(__file__))
class FixedOIDView(AuthOIDView):
@expose("/login/", methods=["GET", "POST"])
def login(self, flag=True):
form = LoginForm_oid()
if form.validate_on_submit():
identity_url = None
for provider in self.appbuilder.sm.openid_providers:
if provider.get("url") == form.openid.data:
identity_url = form.openid.data
if identity_url is None:
flash(self.invalid_login_message, "warning")
return redirect(self.appbuilder.get_url_for_login)
return super().login(flag=flag)
class FixedAirflowSecurityManager(AirflowSecurityManager):
authoidview = FixedOIDView
SECURITY_MANAGER_CLASS = FixedAirflowSecurityManager
Credits
Big thanks to Islam Rzayev for finding out and reporting the issue responsibly and to Daniel Gaspar for very close cooperation on this one and coordinating the disclosure together with the Apache Superset where Flask AppBuilder is also used.
Share