> ## Content Index
> Fetch the complete content index at: https://f4n6.co.uk/llms.txt
> Use this file to discover other available public pages before exploring further.

# Apache Airflow exception-node deserialization permits arbitrary callable execution
- URL: https://f4n6.co.uk/security-feed/apache-airflow-exception-node-deserialization-permits-arbitrary-callable-execution/
- Published: 2026-10-03T13:54:17.000Z
- Updated: 2026-10-03T13:54:17.000Z
- Author: Jeff Davies
- Tags: #security-feed, CVE-2026-33264

## 1\. Executive summary

Apache Airflow's serialization layer reconstructs exception nodes by calling `import_string()` on a class name taken from a serialized blob and instantiating it with arguments from the same blob, with no restriction on what can be imported. A Dag author can place a value in an operator's `executor_config` that causes an arbitrary callable to be imported and invoked, and the code runs in the Scheduler on its normal reconstruction loop and in the API server on any authenticated Dag read such as `GET /api/v2/dags/{dag_id}/details`. Both components hold the metadata database credentials and the JWT signing secret, and the Airflow security model states neither should ever execute Dag-author code. No non-default configuration is required. This is a different sink from CVE-2026-33264, which covered only the trigger branch of the same deserializer, so deployments that upgraded in response to that advisory remain affected through the exception branch and must upgrade again to apache-airflow 3.3.1 or later.

## 2\. Regulatory framing

| Article            | Trigger (the fact in this item)                                                                                                                                                                                                                           | Practical impact                                                                                                                                         |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| DORA Art. 17       | The flaw executes Dag-author code inside the Scheduler and API server, the two components holding the metadata database credentials and the JWT signing secret, so an exploited instance is an ICT-related incident requiring a managed response process. | Clients running Airflow in a DORA scope must be able to detect, contain and recover from Scheduler or API-server compromise, not only patch the package. |
| DORA Art. 28       | Airflow is an ICT third-party dependency whose compromise reaches the metadata database and JWT signing secret, which are the trust anchors for the rest of the deployment.                                                                               | Third-party risk records for Airflow must reflect that a single package upgrade closes an execution path in two privileged components.                   |
| NIS2 Art. 21(2)(d) | The vulnerability is in a software component obtained through the supply chain, and the fix is a version upgrade to apache-airflow 3.3.1 or later.                                                                                                        | Supply chain security measures must include tracking this advisory and verifying the upgrade across all Airflow deployments.                             |

## 3\. Technical analysis & attack chain

The vulnerability is a deserialization flaw in Airflow's serialization layer, classified CWE-502 (Deserialization of Untrusted Data). The exception-node reconstruction path calls `import_string()` on a class name read from the serialized blob and instantiates it with arguments from the same blob, with no allowlist on the imported class. An operator's `executor_config` reaches that branch, so a Dag author controls the class name and arguments that the deserializer imports and invokes.

Confirmed attack chain:

1. A Dag author places a value in an operator's `executor_config` that names an arbitrary callable and its arguments.
2. The value is serialized into the Dag blob as part of normal Dag processing.
3. The Scheduler reconstructs the serialized Dag in its normal loop, with no request involved, and reaches the exception-node branch.
4. The deserializer calls `import_string()` on the attacker-supplied class name and instantiates it with the attacker-supplied arguments, importing and invoking an arbitrary callable such as `subprocess.check_output`, or `builtins.eval` on the `builtins`\-prefixed variant.
5. The same reconstruction occurs in the API server on any authenticated read of the Dag, for example `GET /api/v2/dags/{dag_id}/details`.
6. Code executes in the Scheduler and API server contexts, both of which hold the metadata database credentials and the JWT signing secret.

No non-default configuration is required for any of these steps. The execution does not depend on a request reaching the Scheduler; the Scheduler triggers it on its own reconstruction loop, which means an affected deployment can execute the payload without any external interaction once the Dag is present.

The affected components are the Scheduler and the API server. The Airflow security model states that neither should execute Dag-author code, so this is a boundary violation as well as a code-execution flaw. The metadata database credentials and the JWT signing secret are both reachable from the executing context, which makes the impact of a successful trigger broader than the Airflow process itself.

This is a different sink from CVE-2026-33264, which covered only the trigger branch of the same deserializer. Deployments that upgraded in response to the CVE-2026-33264 advisory are still affected through the exception branch and must upgrade again. The fix in apache-airflow 3.3.1 restricts the imported class to a subclass of `BaseException`.

Discrepancy note: the verified reference data records CVE-2026-33264 at CVSS 9.8 CRITICAL with CWE-502, and the source describes this item as a different sink from that CVE. The source does not provide a CVSS score or CWE for the exception-branch issue itself, so no severity is assigned to it here beyond the CWE-502 classification carried by the deserialization mechanism.

## 4\. Mitigation & containment

P1 (within 24h):

- Upgrade apache-airflow to 3.3.1 or later on every deployment, including Scheduler and API server instances. This is the vendor fix and it closes the exception branch by restricting the imported class to a subclass of `BaseException`.
- If an immediate upgrade is not possible, restrict who can author or modify Dags and who can write to `executor_config`, and treat any Dag author as holding code-execution capability in the Scheduler and API server.
- Rotate the Airflow metadata database credentials and the JWT signing secret on any deployment where a Dag author is not fully trusted, because both are reachable from the executing context.

P2 (within 72h):

- Audit Dag definitions for `executor_config` values that reference callables outside the expected operator set, and for any `builtins`\-prefixed or `subprocess`\-prefixed values.
- Review API server access logs for authenticated reads of `GET /api/v2/dags/{dag_id}/details` from accounts that do not normally read Dag details.

P3 (within 7 days):

- Confirm the upgrade across all environments, including any deployment that was patched for CVE-2026-33264, since that patch does not cover the exception branch.
- Add the Airflow version check to the software inventory so future advisories against the serialization layer are matched against the deployed version.

## 5\. Indicators of compromise

No indicators of compromise available in the source material.

The source describes observable behaviours rather than atomic indicators. The table below lists the behaviours a defender can look for.

### Behavioural indicators

| behaviour                                                                                                                  | where to observe                                                             | confidence                                                              |
| -------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| Scheduler reconstructs a serialized Dag and imports a class named in executor\_config that is not a BaseException subclass | Scheduler process logs and process execution telemetry on the Scheduler host | high, from the source description of the vulnerable path                |
| API server imports a class named in a serialized Dag on an authenticated read of GET /api/v2/dags/{dag\_id}/details        | API server logs and process execution telemetry on the API server host       | high, from the source description of the vulnerable path                |
| executor\_config values referencing subprocess.check\_output or builtins.eval                                              | Dag definition files and the serialized Dag store                            | medium, these are the examples the source gives, not an exhaustive list |

## 6\. Detection

The source gives distinctive artefacts for the vulnerable path: the `import_string()` call on a class name from the serialized blob, the `executor_config` field, and the example callables `subprocess.check_output` and `builtins.eval`. These are artefacts of the vulnerable code path and the example payloads, so a string-based rule can match them.

```yara
rule Apache_Airflow_Exception_Node_Deserialization
{
    meta:
        author = "Adverse Trace"
        date = "2026-10-03"
        reference = "https://github.com/advisories/GHSA-8prw-8m6x-8w6f"
        description = "Detects strings associated with the Airflow exception-node deserialization path and its example payloads"
    strings:
        $import_string = "import_string" ascii
        $executor_config = "executor_config" ascii
        $subprocess_check_output = "subprocess.check_output" ascii
        $builtins_eval = "builtins.eval" ascii
        $base_exception = "BaseException" ascii
    condition:
        uint32(0) != 0x04034b50 and
        (
            ($import_string and $executor_config) or
            $subprocess_check_output or
            $builtins_eval
        )
}

```

```yaml
title: Airflow exception-node deserialization callable import
id: 8f3c2a91-4d7e-4b1a-9c2e-6a5f0d3b7e21
status: experimental
description: Detects Scheduler or API server processes importing a callable named in a serialized Dag executor_config, consistent with the Airflow exception-node deserialization path.
author: Adverse Trace
date: 2026-10-03
references:

    - https://github.com/advisories/GHSA-8prw-8m6x-8w6f
logsource:
    category: process_creation
    product: linux
detection:
    selection_airflow:
        Image|endswith:

            - '/airflow'
            - '/airflow-scheduler'
            - '/airflow-api-server'
    selection_callable:
        CommandLine|contains:

            - 'subprocess.check_output'
            - 'builtins.eval'
    condition: selection_airflow and selection_callable
falsepositives:

    - Legitimate Dag definitions that reference these callables in executor_config
level: high

```

## CVE assessment

1 referenced CVE — 1 critical (CVSS ≥ 9.0)

| CVE                                                                              | CVSS         | Exploited | EPSS | Summary                                                                                                                       |
| -------------------------------------------------------------------------------- | ------------ | --------- | ---- | ----------------------------------------------------------------------------------------------------------------------------- |
| [CVE-2026-33264](https://nvd.nist.gov/vuln/detail/CVE-2026-33264?ref=f4n6.co.uk) | 9.8 Critical | —         | 2%   | A bug in BaseSerialization.deserialize() allowed unrestricted import\_string() of attacker-controlled class paths when the S… |

## 7\. Sources

- GitHub Advisory Database, "Apache Airflow exception-node deserialization permits arbitrary callable execution", https://github.com/advisories/GHSA-8prw-8m6x-8w6f, published 2026-08-12
- NVD, CVE-2026-58076, https://nvd.nist.gov/vuln/detail/CVE-2026-58076
- Apache Airflow pull request 68511, https://github.com/apache/airflow/pull/68511
- Apache Airflow mailing list thread, https://lists.apache.org/thread/t81p688t15jozxsng8521o60nh2kfsos
- Apache Airflow release 3.3.1, https://github.com/apache/airflow/releases/tag/3.3.1
- PyPA advisory database, PYSEC-2026-3991, https://github.com/pypa/advisory-database/tree/main/vulns/apache-airflow/PYSEC-2026-3991.yaml

## 8\. Adverse Trace position

Adverse Trace assesses this as a high-priority upgrade for any client running Apache Airflow, because the vulnerable path executes in the Scheduler without any external request and in the API server on an authenticated read, and both components hold the metadata database credentials and the JWT signing secret. The verified reference data records CVE-2026-33264 at CVSS 9.8 CRITICAL with CWE-502 and not in CISA KEV, and this item is a different sink in the same deserializer, so clients that patched for CVE-2026-33264 are not covered and must upgrade to apache-airflow 3.3.1 or later. The source does not provide a CVSS score for the exception-branch issue, so we do not assign one; the CWE-502 classification and the execution context are the basis for the priority. The example callables in the source are illustrative, not an exhaustive list of what can be imported, so detection should not rely on those strings alone. We will track the Apache Airflow 3.3.1 release and any follow-up advisories against the serialization layer, and we will update this advisory if a CVSS score or exploitation state is published for the exception-branch issue.

---

[Read the original source →](https://github.com/advisories/GHSA-8prw-8m6x-8w6f?ref=f4n6.co.uk)

*Published via PulseTrace — Adverse Trace threat intelligence.*