Apache Airflow: Ignored Airflow Permissions
Description
Apache Airflow, versions 2.8.0 through 2.8.2, has a vulnerability that allows an authenticated user with limited permissions to access resources such as variables, connections, etc from the UI which they do not have permission to access.
Users of Apache Airflow are recommended to upgrade to version 2.8.3 or newer to mitigate the risk associated with this vulnerability
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Apache Airflow 2.8.0–2.8.2 allows authenticated low-privilege users to access restricted UI resources like variables and connections.
Vulnerability
Overview
In Apache Airflow versions 2.8.0 through 2.8.2, a privilege escalation vulnerability exists that allows an authenticated user with limited permissions to access sensitive resources—such as variables and connections—via the UI, even when the user should not have permission to view them [1][2]. The root cause originates from an incorrect mapping of HTTP methods to FAB (Flask-AppBuilder) permissions in the authentication manager. Specifically, the MENU HTTP method was missing from the method-to-action mapping, causing certain menu-level access requests (e.g., for 'Docs' views) to be treated as a standard GET request, thereby bypassing the intended permission checks for these resources [3].
Exploitation & Attack Surface
A low-privileged attacker who already has a valid Airflow session can trigger this vulnerability by navigating to restricted UI endpoints. No special network position is required beyond accessing the Airflow web interface [2]. The flaw is triggered when the user requests a view that is normally only accessible via a menu link (e.g., documentation), but the system incorrectly maps the request to a GET method instead of the MENU method, leading to insufficient authorization checks [3].
Impact
An attacker exploiting this issue gains unauthorized read access to Airflow resources such as connections (which may contain credentials), variables, and other sensitive configuration data exposed through the UI [2][4]. This can lead to data exposure, credential leakage, and potentially further compromise of the Airflow environment.
Mitigation & Status
The vulnerability is patched in Apache Airflow version 2.8.3. Users are strongly recommended to upgrade immediately [2][4]. No known workarounds have been published. The issue was discovered by Alex Liotta and remediated by Vincent (Vincbeck) [4]. It has not yet been added to CISA's Known Exploited Vulnerabilities catalog as of this writing.
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
apache-airflowPyPI | >= 2.8.0, < 2.8.3rc1 | 2.8.3rc1 |
Affected products
3- osv-coords2 versions
>= 2.8.0, < 2.8.3+ 1 more
- (no CPE)range: >= 2.8.0, < 2.8.3
- (no CPE)range: >= 2.8.0, < 2.8.3rc1
- Apache Software Foundation/Apache Airflowv5Range: 2.8.0
Patches
189e7f3e7bdf2Add "MENU" permission in auth manager (#37881)
5 files changed · +22 −18
airflow/auth/managers/base_auth_manager.py+1 −1 modified@@ -57,7 +57,7 @@ from airflow.www.extensions.init_appbuilder import AirflowAppBuilder from airflow.www.security_manager import AirflowSecurityManagerV2 -ResourceMethod = Literal["GET", "POST", "PUT", "DELETE"] +ResourceMethod = Literal["GET", "POST", "PUT", "DELETE", "MENU"] class BaseAuthManager(LoggingMixin):
airflow/auth/managers/utils/fab.py+1 −1 modified@@ -36,6 +36,7 @@ "GET": ACTION_CAN_READ, "PUT": ACTION_CAN_EDIT, "DELETE": ACTION_CAN_DELETE, + "MENU": ACTION_CAN_ACCESS_MENU, } @@ -48,5 +49,4 @@ def get_method_from_fab_action_map(): """Return the map associating a FAB action to a method.""" return { **{v: k for k, v in _MAP_METHOD_NAME_TO_FAB_ACTION_NAME.items()}, - ACTION_CAN_ACCESS_MENU: "GET", }
airflow/providers/fab/auth_manager/fab_auth_manager.py+4 −11 modified@@ -54,8 +54,6 @@ from airflow.providers.fab.auth_manager.models import Permission, Role, User from airflow.security import permissions from airflow.security.permissions import ( - ACTION_CAN_ACCESS_MENU, - ACTION_CAN_READ, RESOURCE_AUDIT_LOG, RESOURCE_CLUSTER_ACTIVITY, RESOURCE_CONFIG, @@ -263,8 +261,10 @@ def is_authorized_variable( return self._is_authorized(method=method, resource_type=RESOURCE_VARIABLE, user=user) def is_authorized_view(self, *, access_view: AccessView, user: BaseUser | None = None) -> bool: + # "Docs" are only links in the menu, there is no page associated + method: ResourceMethod = "MENU" if access_view == AccessView.DOCS else "GET" return self._is_authorized( - method="GET", resource_type=_MAP_ACCESS_VIEW_TO_FAB_RESOURCE_TYPE[access_view], user=user + method=method, resource_type=_MAP_ACCESS_VIEW_TO_FAB_RESOURCE_TYPE[access_view], user=user ) def is_authorized_custom_view( @@ -463,18 +463,11 @@ def _get_user_permissions(user: BaseUser): """ Return the user permissions. - ACTION_CAN_READ and ACTION_CAN_ACCESS_MENU are merged into because they are very similar. - We can assume that if a user has permissions to read variables, they also have permissions to access - the menu "Variables". - :param user: the user to get permissions for :meta private: """ - perms = getattr(user, "perms") or [] - return [ - (ACTION_CAN_READ if perm[0] == ACTION_CAN_ACCESS_MENU else perm[0], perm[1]) for perm in perms - ] + return getattr(user, "perms") or [] def _get_root_dag_id(self, dag_id: str) -> str: """
airflow/www/security_manager.py+1 −3 modified@@ -39,8 +39,6 @@ from airflow.exceptions import AirflowException from airflow.models import Connection, DagRun, Pool, TaskInstance, Variable from airflow.security.permissions import ( - ACTION_CAN_ACCESS_MENU, - ACTION_CAN_READ, RESOURCE_ADMIN_MENU, RESOURCE_AUDIT_LOG, RESOURCE_BROWSE_MENU, @@ -340,7 +338,7 @@ def _get_auth_manager_is_authorized_method(self, fab_resource_name: str) -> Call # This means the page the user is trying to access is specific to the auth manager used # Example: the user list view in FabAuthManager return lambda action, resource_pk, user: get_auth_manager().is_authorized_custom_view( - fab_action_name=ACTION_CAN_READ if action == ACTION_CAN_ACCESS_MENU else action, + fab_action_name=action, fab_resource_name=fab_resource_name, user=user, )
tests/providers/fab/auth_manager/test_fab_auth_manager.py+15 −2 modified@@ -39,6 +39,7 @@ RESOURCE_DAG, RESOURCE_DAG_RUN, RESOURCE_DATASET, + RESOURCE_DOCS, RESOURCE_JOB, RESOURCE_PLUGIN, RESOURCE_PROVIDER, @@ -140,10 +141,10 @@ def test_is_logged_in(self, mock_get_user, auth_manager): [(ACTION_CAN_DELETE, resource_type), (ACTION_CAN_CREATE, "resource_test")], True, ), - # With permission (testing that ACTION_CAN_ACCESS_MENU gives GET permissions) + # With permission ( api_name, - "GET", + "MENU", [(ACTION_CAN_ACCESS_MENU, resource_type)], True, ), @@ -346,6 +347,18 @@ def test_is_authorized_dag( [(ACTION_CAN_READ, RESOURCE_TRIGGER)], False, ), + # Docs (positive) + ( + AccessView.DOCS, + [(ACTION_CAN_ACCESS_MENU, RESOURCE_DOCS)], + True, + ), + # Without permission + ( + AccessView.DOCS, + [(ACTION_CAN_READ, RESOURCE_DOCS)], + False, + ), ], ) def test_is_authorized_view(self, access_view, user_permissions, expected_result, auth_manager):
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/apache/airflow/pull/37881ghsapatchWEB
- github.com/advisories/GHSA-h574-6646-vfxxghsaADVISORY
- lists.apache.org/thread/b4pffc7w7do6qgk4jjbyxvdz5odrvny7ghsavendor-advisoryWEB
- nvd.nist.gov/vuln/detail/CVE-2024-28746ghsaADVISORY
- www.openwall.com/lists/oss-security/2024/03/13/5ghsaWEB
- github.com/apache/airflow/commit/89e7f3e7bdf2126bbbcd959dc10d65ef92773ccaghsaWEB
- github.com/pypa/advisory-database/tree/main/vulns/apache-airflow/PYSEC-2024-46.yamlghsaWEB
News mentions
0No linked articles in our index yet.